使用find方法后如何获取父元素 (xml.etree.ElementTree)

15 投票
2 回答
29146 浏览
提问于 2025-04-18 09:55

我正在处理一个很大的xml文件,想从不同的元素中提取信息。

import xml.etree.ElementTree as ET
tree = ET.parse('t.xml')
root = tree.getroot()

为了找到这些元素,我使用了一个叫做find的方法:

elm = root.find('.//Element[@elmid="1234"]')

从中我提取信息,另外我还需要父元素的信息。但是,elm.find('..') 只返回 None,具体情况可以在这里查看: https://docs.python.org/3/library/xml.etree.elementtree.html

现在我使用的是以下方法:

prt = root.find('.//Element[@elmid="1234"]/..')     
elm = prt.find('/Element[@elmid="1234"]')

这看起来有点不太自然,但确实有效。

你知道有没有更好的方法吗? 你知道为什么只返回 None 吗?

2 个回答

3

我遇到过类似的问题,于是我想了个办法。其实没有什么东西阻止我们自己添加父级信息。等到不再需要这些信息的时候,我们可以把它去掉。

def addParentInfo(et):
    for child in et:
        child.attrib['__my_parent__'] = et
        addParentInfo(child)

def stripParentInfo(et):
    for child in et:
        child.attrib.pop('__my_parent__', 'None')
        stripParentInfo(child)

def getParent(et):
    if '__my_parent__' in et.attrib:
        return et.attrib['__my_parent__']
    else:
        return None

tree = ...
addParentInfo(tree.getroot())
el = tree.findall(...)[0]
parent = getParent(el)
while parent:
    ...
    parent = getParent(parent)
...
stripParentInfo(tree.getroot())
24

xml.etree 这个库只支持有限的 XPath 功能。关于 .. 这个 XPath 表达式,xml.etree 的文档中提到:

它可以选择父元素。如果路径试图访问起始元素的祖先(也就是调用 find 的那个元素的上级),则返回 None。

直接获取父元素在 xml.etree 这个库中是 不支持的。所以我建议你使用 lxml,在这个库中你可以简单地使用 getparent() 来获取父元素:

elm = root.find('.//Element[@elmid="1234"]')
elm.getparent()

lxml 还完整支持 XPath 1.0,所以 elem.xpath('..') 也可以正常工作。

撰写回答