【问题标题】:how to get xpath of all elements in xml file with default namespace using python?如何使用python获取具有默认命名空间的xml文件中所有元素的xpath?
【发布时间】:2016-07-18 06:32:04
【问题描述】:

我想获取 xml 文件中每个元素的 xpath。

xml 文件:

<root 
xmlns="http://www.w3.org/TR/html4/"
xmlns:h="http://www.w3schools.com/furniture">

<table>
  <tr>
    <h:td>Apples</h:td>
    <h:td>Bananas</h:td>
  </tr>
</table>
</root>

python 代码: 由于默认命名空间中不允许使用空前缀,因此我使用了自己的前缀。

from lxml import etree 
root=etree.parse(open("MyData.xml",'r'))
ns={'df': 'http://www.w3.org/TR/html4/', 'types': 'http://www.w3schools.com/furniture'}
for e in root.iter():
   b=root.getpath(e)
   print b
   r=root.xpath(b,namespaces=ns)
   #i need both b and r here

xpath 是这样的(输出 b)

/*
/*/*[1]
/*/*[1]/*[1]
/*/*[1]/*[1]/h:td

对于具有默认命名空间的元素,我无法正确获取 xpath,对于这些元素名称,它显示为 *。如何正确获取 xpath?

【问题讨论】:

    标签: python xml xpath xml-namespaces elementtree


    【解决方案1】:

    您可以使用getelementpath,它始终以克拉克表示法返回元素,并手动替换命名空间:

    x = """
    <root 
    xmlns="http://www.w3.org/TR/html4/"
    xmlns:h="http://www.w3schools.com/furniture">
    
    <table>
      <tr>
        <h:td>Apples</h:td>
        <h:td>Bananas</h:td>
      </tr>
    </table>
    </root>
    """
    
    from lxml import etree 
    root = etree.fromstring(x).getroottree()
    ns = {'df': 'http://www.w3.org/TR/html4/', 'types': 'http://www.w3schools.com/furniture'}
    for e in root.iter():
        path = root.getelementpath(e)
        root_path = '/' + root.getroot().tag
        if path == '.':
            path = root_path
        else:
            path = root_path + '/' + path
        for ns_key in ns:
            path = path.replace('{' + ns[ns_key] + '}', ns_key + ':')
        print(path)
        r = root.xpath(path, namespaces=ns)
        print(r)
    

    很明显,这个例子表明getelementpath返回的是相对于根节点的路径,比如.dt:table而不是/df:root/df:root/df:table,所以我们使用根元素的tag来手动构建完整路径。

    输出:

    /df:root
    [<Element {http://www.w3.org/TR/html4/}root at 0x37f5348>]
    /df:root/df:table
    [<Element {http://www.w3.org/TR/html4/}table at 0x44bdb88>]
    /df:root/df:table/df:tr
    [<Element {http://www.w3.org/TR/html4/}tr at 0x37fa7c8>]
    /df:root/df:table/df:tr/types:td[1]
    [<Element {http://www.w3schools.com/furniture}td at 0x44bdac8>]
    /df:root/df:table/df:tr/types:td[2]
    [<Element {http://www.w3schools.com/furniture}td at 0x44bdb88>]
    

    【讨论】:

    • - 代码工作正常,但不是从字符串中读取 xml,我想从像 open("MyData.xml",'r') 这样的 xml 文件中读取它。我不知道支持文件读取的 root = etree.fromstring(x).getroottree() 的确切语法。如何做?
    • @mariz 解析一个名为 MyData.xml 的文件,您可以将 root = etree.fromstring(x).getroottree() 替换为 root = etree.parse('MyData.xml') 更多信息在:lxml.de/parsing.html
    猜你喜欢
    • 2011-04-25
    • 1970-01-01
    • 1970-01-01
    • 2011-10-09
    • 2014-09-17
    • 1970-01-01
    • 2012-12-29
    • 2010-10-09
    相关资源
    最近更新 更多