关于python:使用find方法(xml.etree.ElementTree)后获取父元素

Get parent element after using find method (xml.etree.ElementTree)

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

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

要查找元素,我使用find方法:

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

我从中提取信息,此外,我还需要父元素的信息。 但是elm.find('..')仅返回None,如此处记录:
https://docs.python.org/3/library/xml.etree.elementtree.html

现在,我使用以下方法:

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

这对我来说似乎有点不自然,但可以。

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


xml.etree API仅支持XPath的受限版本。 .. XPath表达式状态的xml.etree文档:

Selects the parent element. Returns None if the path attempts to
reach the ancestors of the start element (the element find was called
on).

xml.etree API不支持直接获取父元素。 因此,我建议使用lxml,在这里您可以简单地使用getparent()来获取父元素:

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

lxml也具有完整的XPath 1.0实现,因此elem.xpath('..')也可以工作。


我有一个类似的问题,我有点创意。 事实证明,没有什么阻止我们自己添加育儿信息。 一旦不再需要它,我们以后可以剥离它。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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())