如何使用 ElementTree 查找所有顶级匹配节点?

How can I use ElementTree to find all top level matched nodes?

我有一个未知的 XML 结构,我想在其中找到具有包含 FooBarName 属性的所有节点,这些节点本身没有相似的祖先。也就是说,除子节点外的所有最高级别的匹配节点。

这是我用于查找具有匹配属性的节点的当前原型代码。 ElementTree 没有完整的 XPath 实现,所以我们不能使用 contains().

    found = []
    for node in root.iter():
        if 'FooBar' in node.attrib.get('Name', ''):
            found.append(node)

似乎有一些方法可以通过 .find('..') 获取父级,但是当您从开始的节点调用它时,这也是 returns null

示例输入:

<root>
    <ElementTypeA Name="..........FooBar.">
        ...
        <ElementTypeB Name=".......FooBar......."/>
        <ElementTypeC Name="...FooBar..........."/>
        <ElementTypeD Name="....................."/>
        <ElementTypeE Name="..........FooBar.">
        .....
        </ElementTypeE>
        ...
    </ElementTypeA>

    <ElementTypeF Name="...........">
        <ElementTypeG Name="..........FooBar.">
            ...
            <ElementTypeH Name=".......FooBar......."/>
            <ElementTypeI Name="..........FooBar.">
            .....
            </ElementTypeI>
            ...
        </ElementTypeG>
    </ElementTypeF>
</root>

在上面的输入中,只需要选择ElementTypeA和ElementTypeG。 ElementTypeE 具有匹配的祖先,而 ElementTypeF 不匹配。

这需要递归。

import xml.etree.ElementTree as ET

def recur(node):
    # if this node is a foobar, return a one-item list containing it
    if 'Name' in node.attrib:
        if "FooBar" in node.attrib['Name']:
            return [ node ]
    # otherwise return a list of the results on the children
    found = []
    for child in node:
        found += recur(child)
    return found

tree = ET.parse('test.xml')
root = tree.getroot()
print(recur(root))

输出:

[<Element 'ElementTypeA' at 0x7f3890ef4dd0>, <Element 'ElementTypeG' at 0x7f3890eea310>]