1

I wrote the code below to append a XML SubElement, but it is appending the same code twice:

Python Code:

from xml.etree import ElementTree as ET
tree = ET.parse("sample.xml")
root = tree.getroot()

child = parent = ''
NOTFOUND = 0
pos = 0

for user in root:
    Id = user.get("id")
    if Id == '012345':
        for attr in user:
            attr_name = attr.get('name')
            pos = len(user)
            if attr_name != "attrib3" and NOTFOUND != 1:
                print "#1: ", user.get('id'), attr.get('name')
                NOTFOUND = NOTFOUND + 1
                parent = user
                child = attr
                continue

if NOTFOUND == 1:
    newattr = ET.SubElement(parent,'res',attrib={'name':'attrib3'})
    newattr_first_seem = ET.SubElement(newattr, 'first_seem', attrib={'date':'2018-08-01', 'status':'GRANTED'})
    print "#2: ", newattr.attrib
    parent.append(newattr)

tree.write('sample.xml')

Desired output:

<stop>
    <user id="012345">
        <res name="attrib1">
            <first_seem date="2018-07-31" status="REQUESTED" />
            <last_seem date="2018-07-31" status="INPROCESS" />
        </res>
        <res name="attrib2">
            <first_seem date="2018-07-31" status="REQUESTED" />
            <last_seem date="2018-07-31" status="COMPLETED" />
        </res>
        **<res name="attrib3">
            <first_seem date="2018-08-01" status="GRANTED" />
        </res>**        
    </user>
    <user id="123456">
        <res name="attrib1">
            <first_seem date="2018-07-31" status="REQUESTED" />
            <last_seem date="2018-07-31" status="REQUESTED" />
        </res>
    </user>
</stop>

Output created:

<stop>
    <user id="012345">
        <res name="attrib1">
            <first_seem date="2018-07-31" status="REQUESTED" />
            <last_seem date="2018-07-31" status="INPROCESS" />
        </res>
        <res name="attrib2">
            <first_seem date="2018-07-31" status="REQUESTED" />
            <last_seem date="2018-07-31" status="COMPLETED" />
        </res>
        **<res name="attrib3">
            <first_seem date="2018-08-01" status="GRANTED" />
        </res>
        <res name="attrib3">
            <first_seem date="2018-08-01" status="GRANTED" />
        </res>**
    </user>
    <user id="123456">
        <res name="attrib1">
            <first_seem date="2018-07-31" status="REQUESTED" />
            <last_seem date="2018-07-31" status="REQUESTED" />
        </res>
    </user>
</stop>

Could someone help me to figure out why the new SubElement is being record twice? I put the print and the math controls into the if to be sure it is not looping twice (and it is not doing).

2
  • are you sure that the new SubElement isn't already there in the input xml file? as I see your code, the if statement " if attr_name != "attrib3" and NOTFOUND != 1:" evaluates to True just in the first iteration of your for loop and it doesn't even check whether attribute3 exists or not. Commented Aug 3, 2018 at 12:01
  • Hi Ai Da, yes I am sure the attrib3 is not in the source file when first run the script, I am sure and I put the 'if' just to guarantee a second append could happen after the first one when NOTFOUND will be update from 0 to 1 Commented Aug 3, 2018 at 12:42

1 Answer 1

1

Use ET.dump(newattr)

Ex:

from xml.etree import ElementTree as ET
tree = ET.parse(filename)
root = tree.getroot()

parent = ''
NOTFOUND = False

for user in root:
    Id = user.get("id")
    if Id == '012345':
        if "attrib3" not in [attr.get('name') for attr in user]:  
            print user, "----"          
            NOTFOUND = True
            parent = user

if NOTFOUND:
    newattr = ET.SubElement(parent,'res',attrib={'name':'attrib3'})
    newattr_first_seem = ET.SubElement(newattr, 'first_seem', attrib={'date':'2018-08-01', 'status':'GRANTED'})
    print "#2: ", newattr.attrib
    ET.dump(newattr)    #Update!!!!

tree.write(filename)
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much Rakesh :)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.