首页 > 解决方案 > 在 lxml 中查找具有未知名称空间的元素

问题描述

我有一个包含多个级别的 XML。每个级别都可以附加命名空间。我想要find一个我知道其名称但不知道其名称空间的特定元素。例如:

my_file.xml

<?xml version="1.0" encoding="UTF-8"?>
<data xmlns="aaa:bbb:ccc:ddd:eee">
  <country name="Liechtenstein" xmlns="aaa:bbb:ccc:liechtenstein:eee">
    <rank updated="yes">2</rank>
    <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>
import lxml.etree as etree

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

cntry_node = root.find('.//country')

以上find不返回任何内容cntry_node。在我的真实数据中,层次比这个例子更深。lxml 文档讨论了命名空间。当我这样做时:

root.nsmap

我看到这个:

{None: 'aaa:bbb:ccc:ddd:eee'}

如果有人可以解释如何访问完整nsmap和/或如何将其用于find特定元素?非常感谢。

标签: pythonxmllxml

解决方案


您可以声明所有名称空间,但鉴于示例 xml 的结构,我认为您最好完全忽略名称空间而只使用local-name(); 所以

cntry_node = root.xpath('.//*[local-name()="country"]')
cntry_node

返回

[<Element {aaa:bbb:ccc:liechtenstein:eee}country at 0x1cddf1d4680>,
 <Element {aaa:bbb:ccc:singapore:eee}country at 0x1cddf1d47c0>,
 <Element {aaa:bbb:ccc:panama:eee}country at 0x1cddf1d45c0>]

推荐阅读