Rename object in lxml

Let’s assume we have a xml file like this:

<annotation verified="yes">
  <folder>Annotation</folder>
  <filename>test_file</filename>
  <path>voc/JPEGImages/test_file</path>
  <source>
    <database>Unknown</database>
  </source>
  <size>
    <width>640</width>
    <height>480</height>
    <depth>3</depth>
  </size>
  <segmented>0</segmented>
  <object>
    <name>old_name</name>
    <pose>Unspecified</pose>
    <truncated>0</truncated>
    <difficult>0</difficult>
    <bndbox>
      <xmin>15</xmin>
      <ymin>164</ymin>
      <xmax>206</xmax>
      <ymax>344</ymax>
    </bndbox>
  </object>
</annotation>

Now I want to change the name of all objects in a given xml file.

I wrote the following function:

def _rename_objects(tree, path, new_name="new_name"):
    root = tree.getroot()
    for rank in root.iter('object'):
        rank.text = str(new_name)
    tree.write(path)

What it does is, it places the text to object. How do I replace the value in ‘name’? Unfortunately tree elements are not really printable for debugging.

<Element 'object' at 0x11235d400>

New values after _rename_objects look like this:

  <segmented>0</segmented>
  <object>new_name<name>old_name</name>
    <pose>Unspecified</pose>

Answer

You need to use [0] index to get node content instead of the node itself.

rank <Element object>
rank[0] <Element name>

for rank in root.iter("object"):
    rank[0].text = str(new_name)

Output:

<name>new_name</name>