带有 xpath 的 python etree 和带有前缀的命名空间

标签 python xml-namespaces elementtree prefix

我找不到信息,如何使用命名空间解析我的 XML:

我有这个 xml:

<par:Request xmlns:par="http://somewhere.net/actual">
  <par:actual>blabla</par:actual>
  <par:documentType>string</par:documentType>
</par:Request>

并尝试解析它:

dom = ET.parse(u'C:\\filepath\\1.xml')
rootxml = dom.getroot()
for subtag in rootxml.xpath(u'//par:actual'):
    #do something
    print(subtag)

并得到异常,因为它不知道 namespace 前缀。 是否有解决该问题的最佳方法,计算该脚本将不知道它将要解析的文件和将要搜索的标签?

搜索网络和 stackoverflow 我发现,如果我会在那里添加:

namespace = {u'par': u"http://somewhere.net/actual"}
for subtag in rootxml.xpath(u'//par:actual', namespaces=namespace):
    #do something
    print(subtag)

行得通。完美的。但是我不知道我将解析哪个 XML,并且我的脚本也不知道搜索标记(例如 //par:actual)。因此,我需要找到以某种方式从 XML 中提取 namespace 的方法。

我找到了很多方法,如何提取命名空间URI,比如:

print(rootxml.tag)
print(rootxml.xpath('namespace-uri(.)'))
print(rootxml.xpath('namespace-uri(/*)'))

但是我应该如何提取前缀来创建 ElementTree 需要我提供的字典?我不想在 xml 主体上使用正则表达式怪物来提取前缀,我相信必须存在支持的方法,不是吗?

也许必须存在一些方法让我通过 ETree 命名空间从 XML 中提取作为字典(正如 ETree 想要的那样!)而无需手动操作?

最佳答案

您不能依赖根元素上的命名空间声明:无法保证声明会在那里,或者文档始终具有相同命名空间的相同前缀。 假设您将通过某种方式传递要搜索的标记(因为您说脚本不知道它),您还应该提供一种传递 namespace 映射的方式。或者使用 James Clark 表示法,例如 {http://somewhere.net/actual}actual(ETXPath 支持此语法,而“普通”xpath 不支持,但如果不需要完整的 xpath,也可以使用其他方法,例如 .findall())

如果您根本不关心前缀,您也可以在 xpath 中使用 local-name() 函数,例如。 //*[local-name()="actual"](但您不会“真的”确定它是正确的“actual”)

关于带有 xpath 的 python etree 和带有前缀的命名空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26991957/

相关文章:

python - 我可以禁用在 ElementTree XMLParser 中解析的实体吗?

python - Pandas 数据帧传播功能或类似功能?

python - pd.DataFrame 中的 Nan(对称矩阵)

python - 在ttk中设置按钮的浮雕

python - 不区分大小写的 xml 和 python

java - JAXB 将不需要的 namespace 声明附加到标记

svg - %tagElement% 上的 href 的命名空间前缀 NS1 未定义,setAttributeNS

Python:忽略 xml.etree.ElementTree 中的 namespace ?

python - 使用 etree 从 xml 标签解析 namespace

PHP - SimpleXML 故障排除中子节点中的命名空间转换