1

I have an xml file like this:

<annotation>
    <folder>my-project-name</folder>
    <filename>red_noisy_snake_0000.png</filename>
    <object>
        <name>red_noisy_snake</name>
        <pose>Unspecified</pose>
        <truncated>Unspecified</truncated>
        <difficult>Unspecified</difficult>
        <bndbox>
            <xmin>618</xmin>
            <ymin>774</ymin>
            <xmax>1037</xmax>
            <ymax>858</ymax>
        </bndbox>
    </object>
</annotation>

And I need to add another 'object' field, similar to the one already present. I have the various values saved in variables (so, 'name', 'pose', 'truncated', the values in 'bndbox'...), and I just need to add it to the original xml file, so that at the end I should end up with something like:

<annotation>
    <folder>red_noisy_snake</folder>   --> CHANGED VALUE
    <filename>red_noisy_snake_0000.png</filename>
    <object>
        <name>red_noisy_snake</name>
        <pose>Unspecified</pose>
        <truncated>0</truncated>
        <difficult>0</difficult>
        <bndbox>
            <xmin>618</xmin>
            <ymin>774</ymin>
            <xmax>1037</xmax>
            <ymax>858</ymax>
        </bndbox>
    </object>
    <object>  --> ADDED OBJECT FIELD
        <name>child_seat</name>
        <pose>Unspecified</pose>
        <truncated>0</truncated>
        <difficult>0</difficult>
        <bndbox>
            <xmin>871</xmin>
            <ymin>25</ymin>
            <xmax>1190</xmax>
            <ymax>566</ymax>
        </bndbox>
    </object>
</annotation>

I know how to add a single, non nested element by using for example:

import xml.etree.ElementTree as ET

in_file = 'wrong.xml'

tree = ET.parse(in_file)
root = tree.getroot()

## add single field
add = ET.Element("tag_name")
add.tail = '\n\t'
add.text = 'content'
root.insert(5,add)
ET.dump(root)

but I can't figure out how to properly create the nested structure I need.

2
  • 2
    I would suggest you split your question into two (or more) questions; it's more likely you'll get responses that way. Commented Feb 17, 2021 at 17:43
  • Thanks, I figured part of the stuff in the original question, I removed it and left only the part I didn't solve yet! Commented Feb 17, 2021 at 19:53

1 Answer 1

1

Fair warning: not everybody likes this approach - and prefer building elements manually - but when it comes to lengthy, nested node structures, I prefer using this template-like approach.

#this assumes all your new variables are located in one list; if not - you'll have to modify
inserts = ["child_seat","Unspecified", 0, 0, 871, 25, 1190, 566]

new_el = f"\n<object>\n        \
<name>{inserts[0]}</name>\n        <pose>{inserts[1]}</pose>\n <truncated>{inserts[2]}</truncated>\n      \
<difficult>{inserts[3]}</difficult>\n        <bndbox>\n            <xmin>{inserts[4]}</xmin>\n           \
<ymin>{inserts[5]}</ymin>\n            <xmax>{inserts[6]}</xmax>\n    \
<ymax>{inserts[7]}</ymax>\n        </bndbox>\n </object>\n"

add = ET.fromstring(new_el)
root.insert(3,add)
print(ET.tostring(root).decode())

The output should be what you're looking for.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.