ElementTree 会生成自己的 nsmap 而 lxml.etree 不会吗?

Does ElementTree generate its own nsmap while lxml.etree does not?

lxml.etree 中解释了 nsmap 的性质。 鉴于以下XML和解析代码,我尝试ElementTree.dumpetree.dump查看。 ET的显示显示了各种命名空间ns1ns2等。这是否意味着ET实际上生成了内部命名空间?如果可以,我们能否或如何使用它,例如,搜索我们知道其名称但不知道其 URI 的元素?

my_xml.xml

<?xml version="1.0" encoding="UTF-8"?>
<data>
  <country name="Liechtenstein" xmlns="aaa:bbb:ccc:liechtenstein:eee">
    <rank updated="yes">2</rank>
    <holidays>
      <christmas>Yes</christmas>
    </holidays>
    <year>2008</year>
    <gdppc>141100</gdppc>
    <neighbor name="Austria" direction="E"/>
    <neighbor name="Switzerland" direction="W"/>
  </country>
  <country name="Singapore" xmlns="aaa:bbb:ccc:singapore:eee">
    <continent>Asia</continent>
    <holidays>
      <christmas>Yes</christmas>
    </holidays>
    <rank updated="yes">5</rank>
    <year>2011</year>
    <gdppc>59900</gdppc>
    <neighbor name="Malaysia" direction="N"/>
  </country>
  <country name="Panama" xmlns="aaa:bbb:ccc:panama:eee">
    <rank updated="yes">69</rank>
    <year>2011</year>
    <gdppc>13600</gdppc>
    <neighbor name="Costa Rica" direction="W"/>
    <neighbor name="Colombia" direction="E"/>
  </country>
</data>

parsing.py

import lxml.etree as etree

tree = etree.parse('my_xml.xml')
root = tree.getroot()

ET.dump

<ns0:data xmlns:ns0="aaa:bbb:ccc:ddd:eee" xmlns:ns1="aaa:bbb:ccc:liechtenstein:eee" xmlns:ns2="aaa:bbb:ccc:singapore:eee" xmlns:ns3="aaa:bbb:ccc:panama:eee">
  <ns1:country name="Liechtenstein">
    <ns1:rank updated="yes">2</ns1:rank>
    <ns1:year>2008</ns1:year>
    <ns1:gdppc>141100</ns1:gdppc>
    <ns1:neighbor name="Austria" direction="E" />
    <ns1:neighbor name="Switzerland" direction="W" />
  </ns1:country>
  <ns2:country name="Singapore">
    <ns2:continent>Asia</ns2:continent>
    <ns2:holidays>
      <ns2:christmas>Yes</ns2:christmas>
    </ns2:holidays>
    <ns2:rank updated="yes">5</ns2:rank>
    <ns2:year>2011</ns2:year>
    <ns2:gdppc>59900</ns2:gdppc>
    <ns2:neighbor name="Malaysia" direction="N" />
  </ns2:country>
  <ns3:country name="Panama">
    <ns3:rank updated="yes">69</ns3:rank>
    <ns3:year>2011</ns3:year>
    <ns3:gdppc>13600</ns3:gdppc>
    <ns3:neighbor name="Costa Rica" direction="W" />
    <ns3:neighbor name="Colombia" direction="E" />
  </ns3:country>
</ns0:data>

etree.dump

<data xmlns="aaa:bbb:ccc:ddd:eee">
  <country xmlns="aaa:bbb:ccc:liechtenstein:eee" name="Liechtenstein">
    <rank updated="yes">2</rank>
    <year>2008</year>
    <gdppc>141100</gdppc>
    <neighbor name="Austria" direction="E"/>
    <neighbor name="Switzerland" direction="W"/>
  </country>
  <country xmlns="aaa:bbb:ccc:singapore:eee" name="Singapore">
    <continent>Asia</continent>
    <holidays>
      <christmas>Yes</christmas>
    </holidays>
    <rank updated="yes">5</rank>
    <year>2011</year>
    <gdppc>59900</gdppc>
    <neighbor name="Malaysia" direction="N"/>
  </country>
  <country xmlns="aaa:bbb:ccc:panama:eee" name="Panama">
    <rank updated="yes">69</rank>
    <year>2011</year>
    <gdppc>13600</gdppc>
    <neighbor name="Costa Rica" direction="W"/>
    <neighbor name="Colombia" direction="E"/>
  </country>
</data>

ElementTree (ET) 和 lxml 处理命名空间的方式不同

ET 通常不保留输入文档中定义的名称空间前缀,也不存储名称空间是否是 默认名称空间。 ET 还将所有名称空间声明移动到最外层元素。

lxml 通常会保留前缀和默认命名空间。

例如,如果您的输入文档是:

<root xmlns:myprefix="https://www.myuri.com">

或者如果输入具有默认命名空间:

<root xmlns="https://www.myuri.com">

然后 lxml 将保留有关此文档的所有内容,而 ET 可以将其转换为

<root xmlns:ns0="https://www.myuri.com">

ET的修改并没有改变文档的语义,但是如果你想避免这种情况,我认为是唯一的解决方案。

ET 命名空间映射并不优越或更有用

Does this mean the ET actually generate internal namespace? if so, can we or how do we use it, for example, to search for an element whose name we know, but not its URI?

不,我不认为 ET 名称空间映射比您从 lxml 获得的映射更有用(或更少)。在这两种情况下,本质上定义了相同的命名空间并使用了相同的映射。

因为我有 ,知道元素名称但不知道其命名空间 URI 的情况并不常见。如果元素的命名空间 URI 是不可预测的并且不是先验的,这是

的原因
  • 更改您的 XML 格式(如果您自己负责)
  • 抱怨这类文件并坚持要求更改(如果其他人负责)

无论如何,在您显示的 XML 文档中,肯定没有按预期方式使用名称空间。每个 country 元素都不需要驻留在自己的命名空间中。