【问题标题】:Find path to the node using ElementTree使用 ElementTree 查找节点的路径
【发布时间】:2020-03-26 08:30:00
【问题描述】:

使用ElementTree,我可以打印特定标签的每次出现(在我的情况下为ExpertSettingsSg ):

#!/usr/bin/env python3

import xml.etree.ElementTree as ET

root = ET.parse('mydoc.xml').getroot()

for children in root:
    value=children.findall('.//ExpertSettingsSg')#tag I'm looking for
    for settings in value:
        if settings.text is not None:
            print(settings.text)

但我没有找到打印发生路径的方法。因为我的 XML 文件有很多级别,并且因为ExpertSettingsSg 几乎可以在每个级别,所以我需要知道ExpertSettingsSg 的来源。我正在寻找类似的东西

配置路径 xxxxxx = /root/xxx/aaaa/bbbb

如果ElementTree 无法实现,还有其他库可以解决问题吗?

谢谢

【问题讨论】:

    标签: python-3.x xml elementtree


    【解决方案1】:

    如果您已经有了节点,您可以遍历树并收集路径(借用 @valdi-bo 的示例):

    from xml.etree import ElementTree as ET
    
    txt ='''<main>
      <x>
        <a>
          <ExpertSettingsSg id="1">x1</ExpertSettingsSg>
        </a>
        <b>
          <dummy>xxxx</dummy>
        </b>
      </x>
      <y>
        <c>
          <dummy>xxxx</dummy>
        </c>
        <d>
          <ExpertSettingsSg id="2">x2</ExpertSettingsSg>
        </d>
        <e>
          <ExpertSettingsSg id="3"/>
        </e>
      </y>
    </main>'''
    
    
    def node_walk(root: ET.Element):
        path_to_node = []
        node_stack = [root]
        while node_stack:
            node = node_stack[-1]
            if path_to_node and node is path_to_node[-1]:
                path_to_node.pop()
                node_stack.pop()
                yield (path_to_node, node)
            else:
                path_to_node.append(node)
                for child in reversed(node):
                    node_stack.append(child)
    
    
    root = ET.ElementTree(ET.fromstring(txt))
    
    for node in root.findall('.//ExpertSettingsSg'):
        for node_path, n in node_walk(root.getroot()):
            if n is node:
                xpath = "/".join(["."] + [n.tag for n in node_path[1:]] + [n.tag])
                print(xpath, node)
                # NOTE: Assert is to just show that the xpath is correct.
                assert root.getroot().find(xpath) == node
    
    

    你会得到这样的输出:

    ./x/a/ExpertSettingsSg <Element 'ExpertSettingsSg' at 0x102cf5b80>
    ./y/d/ExpertSettingsSg <Element 'ExpertSettingsSg' at 0x102cf5db0>
    ./y/e/ExpertSettingsSg <Element 'ExpertSettingsSg' at 0x102cf5e50>
    

    我们可以步行一次并收集所有具有路径的相关节点,而不是多次步行,如下所示:

    xpaths = []
    for node_path, n in node_walk(root.getroot()):
        if n.tag == "ExpertSettingsSg":
            xpath = "/".join(["."] + [n.tag for n in node_path[1:]] + [n.tag])
            xpaths.append(xpath)
    
    for xpath in xpaths: 
        node = root.getroot().find(xpath)
        print(xpath, node)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多