0

Say I have this xml file:

<root>
  <abc>SomeTree1</abc>
  <abc>SomeTree2</abc>
  ...
</root>

and I want to make some operations on the elements in "abc". so I do something like this:

for element in root.findall('./abc')
    ** new_element = function1(element) **

(function1 operates on element and returns an updated version of it). How can I update root with the new_element instead of element? (Maybe something like: element.set(new_element) )?

Thank you

Omer
  • 456
  • 1
  • 3
  • 19
  • 1
    What exactly do you mean by update? Any changes you do to your the elements will be automatically stored in root. – Plasma Oct 01 '15 at 11:54
  • @Plasma I guess it was worth mentioning that these changing are happening inside functions. (I'll edit the question so it will be clearer from now on) – Omer Oct 01 '15 at 12:59

1 Answers1

0

You can pass the root of your tree to the function, then use ElementTree.SubElement to add a new element to your root. I've worked with your example:

import xml.etree.ElementTree as ET

def function(root):
    new_element = ET.SubElement(root, "abc")
    new_element.set("name", "Jonas")
    new_element.text = "This is text"

tree = ET.parse("test.xml")
root = tree.getroot()

# Before
print ET.tostring(root)

for element in root.findall("./abc"):
    function(root)

# After
print ET.tostring(root)

Before:

<root>
  <abc>SomeTree1</abc>
</root>

After:

<root>
  <abc>SomeTree1</abc>
  <abc name="Jonas">This is text</abc>
</root>

Note that I've polished the xml myself, it's not pretty per default. If you want pretty-print, check out this answer.

Edit: Sorry, I thought from the comments that you wanted to add a new element, not replace the current one. For replacing that element, you could either modify the function above to take in an element, then add a new element before removing the original, or you could just modify the existing element directly:

import xml.etree.ElementTree as ET

def function(element):
    element.text = "New text"
    element.tag = "New tag"
    element.set("name", "Jonas")

tree = ET.parse("test.xml")
root = tree.getroot()

# Before
print ET.tostring(root)

for element in root.findall("./abc"):
    function(element)

# After
print ET.tostring(root)

Before:

<root>
  <abc>SomeTree1</abc>
</root>

After:

<root>
  <New tag name="Jonas">New text</New tag>
</root>
Community
  • 1
  • 1
Plasma
  • 1,903
  • 1
  • 22
  • 37
  • That is what I tried, and the elements were not updated on root. I'll see again if I did something wrong but I don't think so. Changing the value of element in a function doesn't change it outside that function. – Omer Oct 03 '15 at 21:49