Get parent element after using find method (xml.etree.ElementTree)
I had a similar problem and I got a bit creative. Turns out nothing prevents us from adding the parentage info ourselves. We can later strip it once we no longer need it.
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())
The xml.etree
API only supports a limited version of XPath. The xml.etree
docs for the ..
XPath expression state:
Selects the parent element. Returns None if the path attempts to reach the ancestors of the start element (the element find was called on).
Directly getting the parent element is not supported in the xml.etree
API. I would therefore recommend to use lxml
, where you can simply use getparent()
to get the parent element:
elm = root.find('.//Element[@elmid="1234"]')
elm.getparent()
lxml
also has a full XPath 1.0 implementation, so elem.xpath('..')
would work as well.