ElementTree是否自动生成内部nsmap而lxml.etree不生成?如何用其查找未知命名空间元素
问题解答
关于ET输出的ns前缀本质
标准库xml.etree.ElementTree(简称ET)输出的ns0、ns1这类前缀,是ET做序列化输出时临时生成的别名,不属于文档内置的固定命名空间配置,也不会存储在元素的属性中。lxml原生的etree.dump不会做这种自动别名转换,会保留XML原有的命名空间声明结构,所以输出里不会出现自动生成的ns前缀,这就是两个dump结果差异的来源。
这类临时生成的前缀没有复用价值,每次序列化的前缀分配规则可能发生变化,无法用来稳定查询元素。标签已知、命名空间URI未知的元素搜索方案
如果不需要区分命名空间,只按标签名搜索,最便捷的方式是使用XPath的local-name()函数,示例如下:
import lxml.etree as etree tree = etree.parse('my_xml.xml') # 搜索所有标签名为christmas的元素,忽略命名空间 all_christmas = tree.xpath("//*[local-name() = 'christmas']") # 搜索所有标签名为country的元素,忽略命名空间 all_country = tree.xpath("//*[local-name() = 'country']")
如果需要先收集全文档所有命名空间再自定义前缀查询,可以遍历文档提取所有命名空间URI自行映射:
# 收集全文档所有命名空间,自定义前缀映射 ns_map = {} for _, elem in etree.iterwalk(tree, events=('start',)): for prefix, uri in elem.nsmap.items(): if uri not in ns_map.values(): ns_map[f'ns{len(ns_map)}'] = uri # 用自定义前缀查询 all_country = tree.xpath("//*[local-name()='country']", namespaces=ns_map)
内容的提问来源于stack exchange,提问作者Tristan Tran
相关产品推荐
相关产品推荐

