Python处理带命名空间XML需显式声明命名空间映射字典,XPath中用“前缀:标签”形式查找,如ns:channel;默认命名空间也须指定前缀,URI必须完全匹配,不支持*通配符跨空间匹配。

Python处理带命名空间的XML,关键在于正确声明和使用命名空间前缀,否则find、findall等方法会找不到元素。
理解命名空间在ElementTree中的表示方式
ElementTree默认不自动识别XML文档中的xmlns声明。即使XML里写了xmlns="http://example.com/ns",你也不能直接用root.find("item")——必须显式传入命名空间映射字典。
- 命名空间映射是一个字典,键是前缀(可自定义),值是URI字符串
- XPath表达式中需用
prefix:tagname写法,如"ns:item" - 默认命名空间(无前缀的
xmlns="...")也要给它起个前缀,不能留空
使用namespaces参数进行查找
这是最常用也最推荐的方式:构造命名空间字典,传给find、findall、iterfind等方法。
例如有如下XML:
立即学习“Python免费学习笔记(深入)”;
My Feed Post 1
对应代码为:
本文档主要讲述的是Python之模块学习;python是由一系列的模块组成的,每个模块就是一个py为后缀的文件,同时模块也是一个命名空间,从而避免了变量名称冲突的问题。模块我们就可以理解为lib库,如果需要使用某个模块中的函数或对象,则要导入这个模块才可以使用,除了系统默认的模块(内置函数)不需要导入外。希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
import xml.etree.ElementTree as ETtree = ET.parse("feed.xml") root = tree.getroot()
声明命名空间:这里用"ns"作为前缀
ns = {"ns": "https://www.php.cn/link/ff4776b449efb88b35fbf6187af9771e"}
正确查找
channel = root.find("ns:channel", namespaces=ns) title = channel.find("ns:title", namespaces=ns) items = channel.findall("ns:item", namespaces=ns)
处理多个命名空间或带前缀的XML
如果XML中用了多个带前缀的命名空间(如xmlns:dc="http://purl.org/dc/elements/1.1/"),只需在字典中一并声明:
ns = {
"rss": "https://www.php.cn/link/ff4776b449efb88b35fbf6187af9771e",
"dc": "http://purl.org/dc/elements/1.1/"
}
查找 dc:creator
creator = item.find("dc:creator", namespaces=ns)
注意:前缀名(如"dc")可以任意取,只要和XPath中一致即可;URI必须完全匹配XML中声明的值(包括末尾斜杠)。
避免常见坑:默认命名空间与通配符
ElementTree不支持*通配符跨命名空间匹配。不要写root.findall("*:item")——它不会生效。
- 若不确定命名空间,可先用
root.tag打印根元素全名,如{https://www.php.cn/link/ff4776b449efb88b35fbf6187af9771e}rss,从中提取URI - 想忽略命名空间?可用正则提取本地名:
elem.tag.split("}")[-1],再遍历比对,但性能较差,仅作备用 - 第三方库如
lxml支持etree.XPath和更灵活的命名空间处理,适合复杂场景









