John
John

Reputation: 83

Python - How to return parent name when a certain string is found in XML

I have a xml file and i am searching looking for a specific string in it. when that string is found, i want to return it's parent name. here is my xml:

<context>
    <name>AccuCapacityApp</name>
    <message>
        <source>Capacity</source>
        <translation type="unfinished">Kapazität</translation>
    </message>
    <message>
        <source>Charge Level</source>
        <translation type="unfinished"></translation>
    </message>
    <message>
        <source>Sel (Yes)</source>
        <translation type="unfinished">Sel (Ja)</translation>
    </message>
    <message>
        <source>Esc (No)</source>
        <translation type="unfinished">Esc (Nein)</translation>
    </message>
</context>

I want to search for "unfinished" and return "Capacity" as "source" and "AccuCapacityApp" as "Main".

i tried this but it prints nothing:

import xml.etree.ElementTree as ET

file = "work.xml"

tree = ET.parse(file)
for elem in tree.findall('context/message'):
   found = elem.get('unfinished')
   print(found.attrib)

Upvotes: 3

Views: 212

Answers (1)

Doron Cohen
Doron Cohen

Reputation: 1046

You are iterating all message nodes using tree.findall('context/message') but you need the translation nodes (they hold the type attribute). So this will work as a subsitute to your code:

for message in tree.iterfind('.//translation[@type="unfinished"]/..'):
    print(message.attrib)

It will iterate the message nodes caontaining a child translation with attribute type that equals to undefined. For more guidance please read about XPath in Python docs. Notice I used iterfind which is more efficient.

Next, for achieving what you want you will need to use message in order to extract source:

for message in tree.iterfind('.//translation[@type="unfinished"]/..'):
    print("Source: ", message.find('source').text)

In order to get the name tag you will need to get the parent of message. For that see this SE question. Or just get the that tag from tree (tree.find('./name')).

Good luck.

Upvotes: 1

Related Questions