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!

2 Answers 2

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'
Sign up to request clarification or add additional context in comments.

2 Comments

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?
@SergiX44 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.
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)

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.