Nayana
Nayana

Reputation: 1549

How to get grandchild elements from Elementtree in python

Say I have an XML code like this one:

<root>
    <a>
        <b>
           ....
        </b>
        <c>
           ....
        </c>
        <d>
           ....
        </d>
    </a>
    <d><c></c><a></a></d>
</root>

Is there a function to get the grandchildren elements given a certain child node? Foe example, in the XML code above, if I pass 'd', I would like it to return 'c' and 'a'.

I tried getChildren(), but I guess this returns attributes, but not the children elements. I don't even have attributes btw.

Thank you.

Upvotes: 1

Views: 9198

Answers (3)

brice
brice

Reputation: 25039

The root element is iterable:

>>> import xml.etree.ElementTree as ET
>>> xml = "<root><a><b>....</b><c>....</c><d>....</d></a><d><c></c><a></a></d></root>"
>>> root = ET.fromstring(xml)
>>> root
<Element 'root' at 0x7fa86a7ea610>
>>> for child in root:
...     print(child)
... 
<Element 'a' at 0x7fa86a7ea650>
<Element 'd' at 0x7fa86a7ea810>

Getting specific grandchild elements:

>>> root = ET.fromstring(xml)
>>> root.find("d")
[<Element 'd' at 0x10d7869a8>]

The find() method will find the first matching child. Note how this is only the child element. We can find grandchildren elements by iterating the child:

>>> for e in root.find("d"):
...     print(e)
...
<Element 'c' at 0x10d82ec28>
<Element 'a' at 0x10d82ec78>

If you want the tag rather than the ElementTree object:

>>> [e.tag for e in root.find("d")]
['c', 'a']

Note that <Element 'c' at 0x7fce44939650> represents an ElementTree Element object (same as root), whose API is defined in the docs

Upvotes: 3

Atmaram Shetye
Atmaram Shetye

Reputation: 1013

Assuming you have already, parsed the document, [i.getchildren() for i in root.findall('d')] is probably what you want!

To be more generic, you can have a function


def getGrandChildOfTag(tagName, root):
    return [i.getchildren() for i in root.findall(tagName)]

Upvotes: 0

michaelmeyer
michaelmeyer

Reputation: 8205

Given that root is the root of your tree:

>>> [grchild for child in root for grchild in child]
[<Element 'b' at 0xb6cbad4c>, <Element 'c' at 0xb6cbaedc>,
<Element 'd' at 0xb6cbad24>, <Element 'c' at 0xb6cbaaa4>]

Ok so let's write a recursive function the Haskell way:

def recurse(node):
    for child in node:
        print(child)
        recurse(child)

>>> node = root.find('d')
>>> recurse(node)
<Element 'c' at 0xb6cbaaa4>
<Element 'a' at 0xb6cbac0c>

Upvotes: 0

Related Questions