ElementTree - Change subchild value conditionally

Viewed 22

I have just work with XML using ElementTree in my current project. I have a task to change a subchild value based on another subchild value in the same child.

I have created a code for that but somehow feel that there might be a way to improve on this readability wise and performance wise.

Here is my code,

import xml.etree.ElementTree as ET

tree = ET.ElementTree(ET.fromstring("<Properties><Property><Name>KENT</Name><Value>99</Value></Property><Property><Name>JOHN</Name><Value>fifthy</Value></Property></Properties>"))
root = tree.getroot()

change_found = False

for item in root:

    for subItem in item:

        if change_found and subItem.tag == "Value":

            subItem.text = "50"
            change_found = False

        if subItem.tag == "Name" and subItem.text == "JOHN":

            change_found = True


print(ET.tostring(root, encoding='utf8', method='xml'))

As you can see from the code, when the subchild text is "JOHN" and the tag is "Name", it sets the change_found to True. Since the next subchild has a tag of Value, it made the change to the text (from fifty to 50).

The code works fine, but I believe there can be some improvement.

You can assume that the structure of the property is always in this order.

<Property> 
    <Name> Some name </Name>
    <Value> Some value </Value>
<Property>

You can also assume that there are only 1 with has a subchild "NAME" with a text "JOHN"

1 Answers

If I understand you correctly, you can get there more simply, using xpath:

root = ET.fromstring([your string above])
for p in root.findall('.//Property'):
    if p.find('.//Name').text.strip()=="JOHN":
        p.find('.//Value').text="50"

print(ET.tostring(root).decode())

Output:

<Properties>
    <Property>
      <Name>KENT
      </Name>
      <Value>99
      </Value>
    </Property>
    <Property>
      <Name>JOHN
      </Name>
      <Value>50</Value>
    </Property>
  </Properties>
Related