Forrest Guest
Forrest Guest

Reputation: 23

ElementTree findtext doesn't find leaf nodes

I'm using ElementTree to scan an XML string pulled from a text file.

<root>
    <branch_a>
        <leaf>foo</leaf>
    </branch_a>
    <branch_b>
        <another_leaf>bar</another_leaf>
    </branch_b>
</root>

When I parse it and try to find the leaf nodes, I don't get any result:

>>> elem_tree = xml.etree.ElementTree.fromstring(xml_string)
>>> leaf_text = elem_tree.findtext('leaf')
>>> leaf_text is None
True

But when I traverse the tree, everything works fine:

>>> elem_tree.findtext('branch_a/leaf')
'foo'

>>> branch = elem_tree.find('branch_a')
>>> branch.findtext('leaf')
'foo'

Is there a way to have ElementTree scan the whole tree for me? My branch names are dynamic, the leaf I'm looking for could live under any branch.

I was able to do this with minidom, but ran into other limitations. Here's what I was doing there, for reference (error checking stripped out).

>>> xml_doc = xml.dom.minidom.parseString(xml_string)
>>> leaf_node = xml_doc.getElementsByTagName('leaf')
>>> leaf_node[0].firstChild.nodeValue
'foo'

Upvotes: 2

Views: 5375

Answers (2)

korta stebuklė
korta stebuklė

Reputation: 41

I'm doing it this way:

leaf_text = elem_tree.findall('.//leaf')

for x in range(0, len(leaf_text)):
    print leaf_text[x].text

Upvotes: 1

tdelaney
tdelaney

Reputation: 77347

findtext uses an ElementTree style path statement, so you were only scanning the immediate children. This will scan the entire tree (see element xpath):

leaf_text = elem_tree.findtext('.//leaf')

Upvotes: 3

Related Questions