Access ElementTree node parent node

I am using the Python ElementTree built-in module. Direct access to children, but how to relate to parent or sister nodes? - can this be done efficiently without going through the whole tree?

+41
python elementtree
Jan 31 '10 at 5:02
source share
7 answers

There is no direct support in the form of the parent attribute, but you can use the templates described here to achieve the desired effect. The following one-line (from a related message) is proposed to create a child-parent mapping for the entire tree:

 parent_map = dict((c, p) for p in tree.getiterator() for c in p) 
+32
Jan 31
source share
— -

Vinay's answer should still work, but for Python 2.7+ and 3.2+ the following is recommended:

 parent_map = {c:p for p in tree.iter() for c in p} 

getiterator() deprecated in favor of iter() , and it's nice to use the new dict understanding constructor.

Secondly, when creating an XML document, it is possible that the child will have several parents, although this will be deleted after the document is serialized. If that matters, you can try the following:

 parent_map = {} for p in tree.iter(): for c in p: if c in parent_map: parent_map[c].append(p) # Or raise, if you don't want to allow this. else: parent_map[c] = [p] # Or parent_map[c] = p if you don't want to allow this 
+14
Nov 21 '13 at 21:31
source share

You can use xpath ... notation in ElementTree.

 <parent> <child id="123">data1</child> </parent> xml.findall('.//child[@id="123"]...') >> [<Element 'parent'>] 
+4
Oct 22 '15 at 12:18
source share

As mentioned in Get the parent after using the find method (xml.etree.ElementTree) , you have to do an indirect search for the parent. Having xml:

 <a> <b> <c>data</c> <d>data</d> </b> </a> 

Assuming you created an etree element in an xml variable, you can use:

  In[1] parent = xml.find('.//c/..') In[2] child = parent.find('./c') 

Result:

 Out[1]: <Element 'b' at 0x00XXXXXX> Out[2]: <Element 'c' at 0x00XXXXXX> 

A higher parent will be found as: secondparent=xml.find('.//c/../..') <Element 'a' at 0x00XXXXXX>

+3
Nov 24 '15 at 10:19
source share

Another way, if only one parent subElement is required, and the path to the subElement subelement is also known.

 parentElement = subElement.find(xpath+"/..") 
+2
Feb 23 '14 at 2:41
source share

If you use lxml, I managed to get the parent element with the following:

 parent_node = next(child_node.iterancestors()) 
+2
Dec 04 '14 at 4:04
source share

Look at clause 19.7.2.2. section: Supported XPath Syntax ...

Find the parent node using the path:

 parent_node = node.find('..') 
0
Dec 13 '17 at 23:29
source share



All Articles