0

I am trying to modify multiple .xml files that are in a folder and overwrite the files with their original files names.

I can successfully modify one file, but when I try to add code to go through multiple files, nothing changes. Not sure what I am doing wrong. Could anyone assist? Thank you.

Also, a beginner in Python.

Here is the XML file that I am changing:

<annotation>
    <folder>Images</folder>
    <filename>1.jpg</filename>
    <path>/Users/AAA/Desktop/data/imgs</path>
    <source>
        <database>Unknown</database>
    </source>
    <size>
        <width>1021</width>
        <height>1500</height>
        <depth>3</depth>
    </size>
    <segmented>0</segmented>
    <object>
        <name>backpack</name>
        <pose>Unspecified</pose>
        <truncated>1</truncated>
        <difficult>0</difficult>
        <bndbox>
            <xmin>6</xmin>
            <ymin>1</ymin>
            <xmax>1021</xmax>
            <ymax>1466</ymax>
        </bndbox>
    </object>
</annotation>

This is what it should look like:

<annotation>
    <folder>backpack</folder>
    <filename>1.jpg</filename>
    <source>
        <database>backpack</database>
        <annotation>custom</annotation>
        <image>custom</image>
    </source>
    <size>
        <width>1021</width>
        <height>1500</height>
        <depth>3</depth>
    </size>
    <segmented>0</segmented>
    <object>
        <name>backpack</name>
        <pose>Unspecified</pose>
        <truncated>1</truncated>
        <difficult>0</difficult>
        <bndbox>
            <xmin>6</xmin>
            <ymin>1</ymin>
            <xmax>1021</xmax>
            <ymax>1466</ymax>
        </bndbox>
    </object>
</annotation>

Here is my python code attempt to try modify multiple files from a folder:

import xml.etree.ElementTree as ET
import xml.dom.minidom
import os

dir = 'Desktop/python_testing/xml/'

if os.path.isfile(dir):

    mytree = ET.parse(dir, '*.xml')
    myroot = mytree.getroot()

    # changes description of the elements
    for description in myroot.iter('folder'):
        new_desc = 'backpack'
        description.text = str(new_desc)

    for database in myroot.iter('database'):
        new_desc = 'backpack'
        database.tail = '\n\t\t'
        database.text = str(new_desc)

    # adds additional subchild items annotation and image
    source = myroot.find('source')
    annotate = ET.SubElement(source, 'annotation') 
    annotate.tail = '\n\t\t'
    annotate.text = 'custom'

    source = myroot.find('source')
    img = ET.SubElement(source, 'image')
    img.tail = '\n\t'
    img.text = 'custom'
    
    #remove <path> element
    path = myroot.getchildren()[2]
    myroot.remove(path)
    
    mytree.write(dir, '*.xml')
1
  • 1
    Desktop/python_testing/xml/ is a directory, so os.path.isfile() will return False. Commented Sep 2, 2020 at 19:45

1 Answer 1

1

You cannot use ElementTree to open multiple files in a single invocation. Simply loop over them:

# your other imports...
import glob

dir = 'Desktop/python_testing/xml/'

for xml_file in glob.glob(dir + '/*.xml'):
    mytree = ET.parse(xml_file)

    # make your changes here...

    mytree.write(xml_file)
Sign up to request clarification or add additional context in comments.

1 Comment

You're welcome. Actually here there is an unnecessary extra /, but it does no harm and I included the / before the *.xml in case dir doesn't have a trailing slash. (The alternative is to use os.path.join.)

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.