XML 明明有 item 却查不到:识别默认命名空间
XML 上写着 <item>,查询 findall('item') 却返回空列表,先检查祖先元素是否声明了默认命名空间。查询需要匹配命名空间 URI 和本地名。生产方可以更换前缀,只要 URI 和本地名保持一致,消费者的查询就无需跟着改。
1. 本机复现
保存为 xml_lab.py,运行 python xml_lab.py。两个输入具有同样的元素身份,分别使用默认命名空间和显式前缀。
from xml.etree import ElementTree as ET
default = """
<feed xmlns="urn:demo:catalog" xmlns:meta="urn:demo:metadata">
<item id="42" meta:id="m-42">widget</item>
<meta:item>metadata</meta:item>
</feed>
"""
prefixed = """
<c:feed xmlns:c="urn:demo:catalog" xmlns:m="urn:demo:metadata">
<c:item id="42" m:id="m-42">widget</c:item>
<m:item>metadata</m:item>
</c:feed>
"""
ns = {"catalog": "urn:demo:catalog", "meta": "urn:demo:metadata"}
for label, source in (("default namespace", default), ("renamed prefixes", prefixed)):
root = ET.fromstring(source)
assert root.findall("item") == []
(item,) = root.findall("catalog:item", ns)
(metadata,) = root.findall("meta:item", ns)
assert item.tag == "{urn:demo:catalog}item"
assert (item.text, metadata.text) == ("widget", "metadata")
print(f"{label}: {item.text} / {metadata.text}")
assert item.get("id") == "42"
assert item.get("{urn:demo:metadata}id") == "m-42"
assert item.get("{urn:demo:catalog}id") is None
print("attributes:", item.get("id"), item.get("{urn:demo:metadata}id"))
本地实测输出如下。
default namespace: widget / metadata
renamed prefixes: widget / metadata
attributes: 42 m-42
2. 根据完整元素名诊断导入失败
先查看解析后的 element.tag。ElementTree 用 {URI}localname 表示带命名空间的名字。查询时可以直接写该形式,也可以维护一份前缀到 URI 的映射。示例查询里的 catalog 是消费者自定义的前缀,和输入文件用什么前缀无关。
默认命名空间适用于作用域里的无前缀元素,但无前缀属性保持无命名空间。因此 id 和 meta:id 可同时出现,且需要分别读取。导入协议若会变更 URI,可把支持的 URI 当成契约的一部分,在查不到元素时报告收到的完整名字。按本地名全局匹配会把同名业务元素和元数据元素混在一起。
小结
按命名空间 URI 和本地名定位元素。读取属性时单独判断它是否带前缀。
数据来源与检索时间
检索时间 2026-11-13。
| 来源 | URL | 对应内容 |
|---|---|---|
| W3C Namespaces in XML 1.0 | https://www.w3.org/TR/xml-names/#defaulting | 默认命名空间和无前缀属性 |
| Python ElementTree | https://docs.python.org/3.11/library/xml.etree.elementtree.html#parsing-xml-with-namespaces | 带命名空间的 tag 与查询映射 |
核验说明
- Windows、Python 3.11.9 实测两种前缀写法、同名异域元素和两个 id 属性。样本是固定的可信 XML,未测试不可信文档的解析安全或外部 XML Schema。