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

yoopoo picture yoopoo · Jun 16, 2014 · Viewed 21.2k times · Source

I am working with a huge xml-file and try to extract information from different elements.

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

To find the elements I use the find method:

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

From this I extract information and in addition I need information from the parent element. But elm.find('..') returns only None as documented here: https://docs.python.org/3/library/xml.etree.elementtree.html

Now I use the folowing:

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

This looks a bit unnatural to me, but works.

Do you know a better way to do this? Do you know why only None is returned?

Answer

Lukas Graf picture Lukas Graf · Jun 16, 2014

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.