I am asked to update a xml file using python but I am stucked in using a if condition there

Question:

Given below is the xml content I am given with

<motorvehicles>
    <vehicle>
        <registration_no>CBB1456</registration_no>
        <make>Toyota</make>
        <model>Premio</model>
    </vehicle>
    <vehicle>
        <registration_no>PR2245</registration_no>
        <make>Mazda</make>
        <model>Bongo</model>
    </vehicle>
    <vehicle>
        <registration_no>DE2115</registration_no>
        <make>TATA</make>
        <model>Sumo</model>
    </vehicle>
    <vehicle>
        <registration_no>Car7785</registration_no>
        <make>Kia</make>
        <model>Optimas</model>
    </vehicle>
</motorvehicles>

And I am asked to modify the details of the vehicle with registration_no "DE2115" as below..

<registration_no>DE2115</registration_no>
 <make>Nissan</make>
 <model>Skyline</model>

And to finally print the the Registration Numbers of each Nissan vehicle.

Below is my own answer

import xml.etree.ElementTree as ET
vehicle_xml_data_as_string = "<motorvehicles><vehicle><registration_no>CBB1456</registration_no><make>Toyota</make><model>Premio</model></vehicle><vehicle><registration_no>PR2245</registration_no><make>Mazda</make><model>Bongo</model></vehicle><vehicle><registration_no>DE2115</registration_no><make>TATA</make><model>Sumo</model></vehicle><vehicle><registration_no>CAR7785</registration_no><make>Kia</make><model>Optima</model></vehicle></motorvehicles>"
root=ET.fromstring(vehicle_xml_data_as_string)

for registration_no in root.iter('registration_no'):
    if registration_no.text=="DE2115":
        for element in root.iter(tag="make"):
            newmake="Nissan"
            element.text=newmake
        for element in root.iter(tag="model"):
            newmodel="Skyline"
            element.text=newmodel
            
for element in root.iter('make'):
    if element.text=="Nissan":
        for element in root.iter('vehicle'):
            regno=element.find('registration_no').text
            print(regno)

Answer I am supposed get is DE2115
But I am getting all registration numbers instead.Kindly help me with this..i am not much comfortable with xml

Asked By: kavi_02

||

Answers:

One problem looks to be in this block.

for registration_no in root.iter('registration_no'):
    if registration_no.text=="DE2115":
        for element in root.iter(tag="make"):
            newmake="Nissan"
            element.text=newmake
        for element in root.iter(tag="model"):
            newmodel="Skyline"
            element.text=newmodel

I think after you find the correct registration_no, you are then iterating over everything

if registration_no.text=="DE2115":
    for element in root.iter(tag="make"):

setting all 'make's to be 'Nissan'
simmilarly with the model elements

Answered By: Anthony L

Every time you call root.iter it iterates through every element in the tree, each time. so the code block below changes all of the make tags to nissan, not just the one that is under the registration number "DE2115".

if registration_no.text=="DE2115":
    for element in root.iter(tag="make"):
        newmake="Nissan"
        element.text=newmake

Instead you should iterate through each vehicle and check the values of each of the children of the vehicle.

For example:

for element in root.iter('vehicle'):
    regno = element.find("registration_no")
    if regno.text == "DE2115":
        make = element.find("make")
        make.text = "Nissan"
        model = element.find("model")
        model.text ="Skyline"

for element in root.iter('vehicle'):
    if element.find("make").text == "Nissan":
        regno = element.find('registration_no').text
        print(regno)

OUTPUT

DE2115
Answered By: Alexander