python elementtree xml append
Asked Answered
A

2

6

I have some trouble for adding an element to an xml file

I have an xml with this structure:

<Root>
    <Item>
        <ItemId>first</ItemId>
        <Datas>
            <Data>one</Data>
            <Data>two</Data>
            <Data>three</Data>
        </Datas>
    </Item>
    <Item>
        <ItemId>second</ItemId>
        <Datas>
            <Data>one</Data>
            <Data>two</Data>
            <Data>three</Data>
        </Datas>
    </Item>
</Root>

and i want to add data only when the itemid is second, and get an output like this:

<Root>
    <Item>
        <ItemId>first</ItemId>
        <Datas>
            <Data>one</Data>
            <Data>two</Data>
            <Data>three</Data>
        </Datas>
    </Item>
    <Item>
        <ItemId>second</ItemId>
        <Datas>
            <Data>one</Data>
            <Data>two</Data>
            <Data>three</Data>
            <Data>FOUR</Data>
            <Data>FIVE</Data>
        </Datas>
    </Item>
</Root>

Thanks for your help!

Asomatous answered 25/7, 2015 at 21:55 Comment(0)
A
4

It is unclear whether you want how to find where to add the elements or how to add the elements themselves.

For this specific example, for finding where, you could try something like this:

import xml.etree.ElementTree as ET
tree=ET.parse('xml-file.txt')
root=tree.getroot()

for item in root.findall('Item'):
    itemid=item.find('ItemId')
    if(itemid.text=='second'):
        #add elements

for the actual adding part, you might try:

new=ET.SubElement(item[1],'Data')
new.text='FOUR'
new=ET.SubElement(item[1],'Data')
new.text='FIVE'

or

new=ET.Element('Data')
new.text='FOUR'
child[1].append(new)
new=ET.Element('Data')
new.text='FIVE'
child[1].append(new)

There are several other ways to do both parts, but, in general, the documentation is very useful: https://docs.python.org/2/library/xml.etree.elementtree.html

EDIT:

If the "Datas" element is further down, you can use the same Element.find() method as above to find the first occurence of the specified tag. (Element.findall() returns a list of all occurences of the specified tag).

The following should do the trick:

data=item.find('Datas')
new=ET.SubElement(data,'Data')
new.text='FOUR'
new=ET.SubElement(data,'Data')
new.text='FIVE'
Amalea answered 25/7, 2015 at 22:15 Comment(2)
many thanks, your solution is working, but i have another issue: if there is another tag between "<ItemId>" and "<Datas>" it stop to work, how can i find the Datas node and append another Data?Asomatous
@Asomatous I edited the answer to include that information. Just use the Element.find() method as used above to find the first occurence of the tag you want.Amalea
T
1

Following way you can find the Datas node and append element to it.

from lxml import etree
from xml.etree import ElementTree as ET

xml_str = """<Root>
<Item>
    <ItemId>first</ItemId>
    <Datas>
        <Data>one</Data>
        <Data>two</Data>
        <Data>three</Data>
    </Datas>
</Item>
<Item>
    <ItemId>second</ItemId>
    <Datas>
        <Data>one</Data>
        <Data>two</Data>
        <Data>three</Data>
    </Datas>
</Item>
</Root>"""

# build the tree 
tree = etree.fromstring(xml_str)
# get all items nodes 
items = tree.findall('Item')

for item in items:
    # get ItemId text 
    item_id = item.findtext('ItemId')
    if item_id == 'second':
        # get the Datas node
        datas = item.find('Datas')

        # add an element to it
        new_data = ET.SubElement(datas, 'Data')
        new_data.text = 'New Data'

# print the final xml tree 
print etree.tostring(tree)
Toussaint answered 26/7, 2015 at 0:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.