1

I have to parse an xml file & modify the data in a particular tag using Python. I'm using Element Tree to do this. I'm able to parse & reach the required tag. But I'm not able to modify the value. I'm not sure if Element Tree is okay or if I should use TreeBuilder for this.

As you can see below I just want to replace the Not Executed under Verdict with a string value.

-<Procedure> 
    <PreCondition>PRECONDITION: - ECU in extended diagnostic session (zz = 0x03)     </PreCondition>
    <PostCondition/> 
    <ProcedureID>428495</ProcedureID> 
    <SequenceNumber>2</SequenceNumber>
    <CID>-1</CID> 
    <**Verdict** Writable="true">NotExecuted</Verdict>  
</Procedure>

import xml.etree.ElementTree as etree

X_tree = etree.parse('DIAGNOSTIC SERVER.xml')
X_root = X_tree.getroot()

ATC_Name = X_root.iterfind('TestOrder//TestOrder//TestSuite//')

try:
    while(1):
        temp = ATC_Name.next()              
        if temp.tag == 'ProcedureID' and temp.text == str(TestCase_Id[j].text).split('-')[1]:
            ATC_Name.next()
            ATC_Name.next()
            ATC_Name.next().text = 'Pass' <--This is what I want to do   
            ATC_Name.close()
            break
except:
            print sys.exc_info()

I believe my approach is wrong. Kindly guide me with right pointers. Thanks.

3 Answers 3

1

You'd better switch to lxml so that you can use the "unlimited" power of xpath.

The idea is to use the following xpath expression:

//Procedure[ProcedureID/text()="%d"]/Verdict

where %d placeholder is substituted with the appropriate procedure id via string formatting operation.

The xpath expression finds the appropriate Verdict tag which you can set text on:

from lxml import etree

data = """<Procedure>
    <PreCondition>PRECONDITION: - ECU in extended diagnostic session (zz = 0x03)     </PreCondition>
    <PostCondition/>
    <ProcedureID>428495</ProcedureID>
    <SequenceNumber>2</SequenceNumber>
    <CID>-1</CID>
    <Verdict Writable="true">NotExecuted</Verdict>
</Procedure>"""

ID = 428495
tree = etree.fromstring(data)
verdict = tree.xpath('//Procedure[ProcedureID/text()="%d"]/Verdict' % ID)[0]
verdict.text = 'test'

print etree.tostring(tree)

prints:

<Procedure>
    <PreCondition>PRECONDITION: - ECU in extended diagnostic session (zz = 0x03)     </PreCondition>
    <PostCondition/>
    <ProcedureID>428495</ProcedureID>
    <SequenceNumber>2</SequenceNumber>
    <CID>-1</CID>
    <Verdict Writable="true">test</Verdict>
</Procedure>
Sign up to request clarification or add additional context in comments.

1 Comment

lxml and xpath are a great solution to the problem, but I would quibble with the xpath because it assumes an ordering of the siblings that may not be valid in the original docs. How about selecting the parent Procedure and then finding its child Verdict like: '//Procedure[ProcedureID/text()="%d"]/Verdict'?
0

Here is a solution using ElementTree. See Modifying an XML File

import xml.etree.ElementTree as et


tree = et.parse('prison.xml')
root = tree.getroot()
print root.find('Verdict').text #before update
root.find('Verdict').text = 'Executed'

tree.write('prison.xml')

2 Comments

Won't work. The problem is that the OP wants to change the Verdict for an appropriate ProcedureID.
@alecxe He can still leverage this. He said he is already able to get to the specific tag, and just needs help modifying.
0

try this

import xml.etree.ElementTree as et

root=et.parse(xmldata).getroot()
s=root.find('Verdict')
s.text='Your string'

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.