在XML文档中,命名空间用于避免不同XML词汇表中相同标签名的冲突,其通常表现为标签名前带有类似ns:的前缀,或者标签带有xmlns属性定义命名空间URI。当使用Python的xml.etree.ElementTree模块解析这类XML时,直接调用findall方法传入本地标签名无法匹配到目标标签,需要结合命名空间的定义来构造正确的搜索路径。

XML命名空间的基础格式
首先看一个包含命名空间的XML示例,后续的所有解析操作都基于这个示例文件:
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:ns="http://www.example.org/ns">
<ns:user>
<ns:name>张三</ns:name>
<ns:age>25</ns:age>
</ns:user>
<ns:user>
<ns:name>李四</ns:name>
<ns:age>30</ns:age>
</ns:user>
</root>
上面的XML中,xmlns:ns="http://www.example.org/ns"定义了命名空间前缀ns对应的URI为http://www.example.org/ns,所有带ns前缀的标签都属于这个命名空间。
方法一:直接使用带命名空间URI的标签路径
ElementTree的findall方法支持使用{命名空间URI}本地标签名的格式来匹配带命名空间的标签,这是最直接的方式。
import xml.etree.ElementTree as ET
# 解析XML文件
tree = ET.parse("test.xml")
root = tree.getroot()
# 定义命名空间URI
ns_uri = "http://www.example.org/ns"
# 匹配所有ns:user标签,注意格式是{URI}本地标签名
user_nodes = root.findall(f"{{{{ns_uri}}}}user")
for user in user_nodes:
# 匹配user下的ns:name标签
name = user.find(f"{{{{ns_uri}}}}name").text
age = user.find(f"{{{{ns_uri}}}}age").text
print(f"姓名:{name},年龄:{age}")
运行上述代码,会输出两个用户的信息。这里需要注意,Python的f-string中如果大括号需要原样输出,需要写两个大括号,所以{{ns_uri}}会被替换为{http://www.example.org/ns},构造出正确的标签路径。
方法二:使用命名空间字典简化路径编写
如果XML中涉及多个命名空间,或者命名空间URI较长,每次都写完整的URI格式会比较繁琐,此时可以使用命名空间字典来简化操作。
import xml.etree.ElementTree as ET
tree = ET.parse("test.xml")
root = tree.getroot()
# 定义命名空间字典,键是前缀(可以自定义,不需要和XML中的前缀一致),值是命名空间URI
namespaces = {
"ns": "http://www.example.org/ns"
}
# 使用字典时,路径格式为 前缀:本地标签名,findall的第二个参数传入命名空间字典
user_nodes = root.findall("ns:user", namespaces)
for user in user_nodes:
name = user.find("ns:name", namespaces).text
age = user.find("ns:age", namespaces).text
print(f"姓名:{name},年龄:{age}")
这种方式的可读性更强,尤其是当有多个命名空间时,只需要在字典中定义一次URI,后续路径中直接使用自定义的前缀即可,不需要重复写冗长的URI。
常见问题说明
- 如果findall返回空列表,首先检查命名空间URI是否和XML中定义的一致,URI的大小写、路径都必须完全匹配。
- XML中如果没有显式定义命名空间前缀,而是用默认命名空间(
xmlns="URI"),此时标签的路径需要写成{URI}标签名,或者使用字典时给默认命名空间自定义一个前缀。 - 如果需要匹配所有命名空间下的某个本地标签名,可以使用XPath的
local-name()函数,但需要注意ElementTree的基础版本对XPath支持有限,复杂场景可以使用lxml库。
两种方案对比
| 方案 | 优势 | 适用场景 |
|---|---|---|
| 直接使用带URI的标签路径 | 不需要额外定义字典,代码更简洁 | 命名空间少、URI短的场景 |
| 使用命名空间字典 | 可读性强,维护方便,适合多命名空间场景 | 命名空间多、URI长的复杂XML解析 |
PythonXMLnamespacefindallElementTree修改时间:2026-06-20 03:42:19