简体   繁体   中英

Appending and formatting a new SubElement via ElementTree

Using the following code, I can successfully add a subElement where I want, and functionally it works. For readability, I want to format the way item.append inserts the new sub elements. My Code:

import xml.etree.ElementTree as ET

tree = ET.parse(file.xml)
root = tree.getroot()

for items in root.iter('items'):
    item = ET.SubElement(items, 'item')
    item.append((ET.fromstring('<item>cat</item>')))    

tree.write('output.xml')

XML File:

<interface>
    <object>
        <items>
            <item>dog</Item>
        </items>
    </object>
</interface>

Expected output:

<interface>
    <object>
        <items>
            <item>dog</item>
            <item>cat</item>
        </items>
    </object>
</interface>

Actual output:

<interface>
    <object>
        <items>
            <item>dog</item>
            <item><item>cat</item></item></items>
    </object>
</interface>

Usually I wouldn't care about how it formats the output.xml file. However, I will be adding <item> subElements in a while loop, so when I have 4 or 5 additions, the code will get a little sloppy for readability's sake.

I have looked at a lot of similar questions concerning this, but they are either unanswered, or don't apply specifically to what I am trying to do.

Here is my code in the while loop, just incase it will add more clarification:

import xml.etree.ElementTree as ET

tree = ET.parse(file.xml)
root = tree.getroot()

while True:

    item_add = input("Enter item to add: 'n")
    item_string = '<item>'
    item_string += item_add
    item_string += '</item>'

    for items in root.iter('items'):
        item = ET.SubElement(items, 'item')
        item.append((ET.fromstring(item_string)))   

tree.write('output.xml')

#Code asking for more input, if none break out of loop

I appreciate any help in advance.

Consider using .find() to walk down to your needed node and then simply use SubElement to add. No need for string versions of markup when working with DOM libraries like etree :

import xml.etree.ElementTree as ET

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

while True:
    item_add = input("Enter item to add: ")

    if item_add == 'x':
        break

    items = root.find('object').find('items')
    tmp = ET.SubElement(items, 'item')
    tmp.text = item_add

# PRINT TO SCREEN
print(ET.tostring(root).decode('utf-8'))

# SAVE TO FILE
tree.write('output.xml')

Output (after entering cat, frog, zebra in inputs, use x to end loop)

<interface>
    <object>
        <items>
            <item>dog</item>
        <item>cat</item><item>frog</item><item>zebra</item></items>
    </object>
</interface>

Use built-in mini.dom or third-party lxml for pretty printing .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM