Search code examples
pythonpython-3.xxmlxml-parsingxml.etree

How to insert elements into a nested XML using Python?


I have an XML in the following form

<PROJECT>
    <UPDATE_TYPE>FULL</UPDATE_TYPE>
    <PROJECT_NAME>GEN20x_BALBOA</PROJECT_NAME>
    <AAA>000</AAA>
    <BBB>CIVIC</BBB>
    <CCC>ECE</CCC>
    <BLOCK>
        <BLOCK1>
            <TYPE>BOOT</TYPE>
            <TYPE>BOOT</TYPE>
            <TASK>
                <INSTALL_OPTIONS softwareType="aaa" />
                <INSTALL_OPTIONS softwareType="aaa" />
                <INSTALL_OPTIONS softwareType="qqq" />
            </TASK>
        </BLOCK1>
    </BLOCK>
</PROJECT>

I need to insert another <INSTALL_OPTIONS> inside TASK tag, the result thus should look like this

<PROJECT>
    <UPDATE_TYPE>FULL</UPDATE_TYPE>
    <PROJECT_NAME>GEN20x_BALBOA</PROJECT_NAME>
    <AAA>000</AAA>
    <BBB>CIVIC</BBB>
    <CCC>ECE</CCC>
    <BLOCK>
        <BLOCK1>
            <TYPE>BOOT</TYPE>
            <TYPE>BOOT</TYPE>
            <TASK>
                <INSTALL_OPTIONS softwareType="aaa" />
                <INSTALL_OPTIONS softwareType="aaa" />
                <INSTALL_OPTIONS softwareType="qqq" />

                <INSTALL_OPTIONS softwareType="new"/>
            </TASK>
        </BLOCK1>
    </BLOCK>
</PROJECT>

I have tried 'insert' operation but coudn't access the nested parts of XML

new = et.Element("INSTALL_OPTIONS")
new.attrib = {softwareType:"new"}
root.insert(5,new)

But the nested insertion didn't happen. How to insert element inside the nested list?


Solution

  • Something like the below

    import xml.etree.ElementTree as ET
    
    xml = '''<PROJECT>
        <UPDATE_TYPE>FULL</UPDATE_TYPE>
        <PROJECT_NAME>GEN20x_BALBOA</PROJECT_NAME>
        <AAA>000</AAA>
        <BBB>CIVIC</BBB>
        <CCC>ECE</CCC>
        <BLOCK>
            <BLOCK1>
                <TYPE>BOOT</TYPE>
                <TYPE>BOOT</TYPE>
                <TASK>
                    <INSTALL_OPTIONS softwareType="aaa" />
                    <INSTALL_OPTIONS softwareType="aaa" />
                    <INSTALL_OPTIONS softwareType="qqq" />
                </TASK>
            </BLOCK1>
        </BLOCK>
    </PROJECT>'''
    
    root = ET.fromstring(xml)
    task = root.find('.//TASK')
    io = ET.SubElement(task, 'INSTALL_OPTIONS')
    io.attrib['softwareType'] = 'new'
    for io in task:
        print(io.attrib)
    

    output

    {'softwareType': 'aaa'}
    {'softwareType': 'aaa'}
    {'softwareType': 'qqq'}
    {'softwareType': 'new'}