Reputation: 485
My XML:
<animals>
<animal name="fox" fullname="fullfox"></animal>
<animal name="dog" fullname="halfdog"><food>milk</food><food>rice</food><food>meat</food> </animal>
<animal name="cow" fullname="doublecow"><food>grass</food></animal>
<animal name="blabla" fullname="fullbla"></animal>
</animals>
I'm trying to parse this XML to get same XML as output.
doc = ET.parse("an.xml")
root = doc.getroot() #Returns the root element for this tree.
root_new = ET.Element("animals")
for child in root:
name = child.attrib['name']
fullname = child.attrib['fullname']
for g in root.findall("*/food"):
animal = ET.SubElement(root_new, "animal")
food = ET.SubElement(animal, "food")
food.text = g.text
animal.set("name",name)
animal.set("fullname",fullname)
tree = ET.ElementTree(root_new)
tree.write(sys.stdout)
But am getting only last value
<animals>
<animal fullname="fullbla" name="blabla"><food>milk</food></animal>
<animal fullname="fullbla" name="blabla"><food>rice</food></animal>
<animal fullname="fullbla" name="blabla"><food>meat</food></animal>
<animal fullname="fullbla" name="blabla"><food>grass</food></animal>
</animals>
And food node also wrong, how to iterate exactly like my input XML?
Upvotes: 1
Views: 133
Reputation: 421
You need a nested loop:
for child in root:
name = child.attrib['name']
fullname = child.attrib['fullname']
# create "animal" here
animal = ET.SubElement(root_new, "animal")
animal.set("name",name)
animal.set("fullname",fullname)
for g in child.findall("food"):
# create "food" here
food = ET.SubElement(animal, "food")
food.text = g.text
Upvotes: 2
Reputation: 19114
There are two problems. The first is your indentation - I assume those are meant to be nested loops. The second problem is that you're using root.findall
, which means that you are getting all food
items regardless of which node they are in. Try this instead:
...
for child in root:
name = child.attrib['name']
fullname = child.attrib['fullname']
animal = ET.SubElement(root_new, 'animal')
for g in child.findall("food"):
food = ET.SubElement(animal, "food")
food.text = g.text
animal.set('name', name)
animal.set('fullname', fullname)
Upvotes: 1
Reputation: 3106
your code should look like this
doc = ET.parse("test.xml")
root = doc.getroot() #Returns the root element for this tree.
root_new = ET.Element("animals")
for child in root:
name = child.attrib['name']
fullname = child.attrib['fullname']
animal = ET.SubElement(root_new, "animal")
animal.set("name",name)
animal.set("fullname",fullname)
for g in child.findall("food"):
food = ET.SubElement(animal, "food")
food.text = g.text
tree = ET.ElementTree(root_new)
tree.write(sys.stdout)
Upvotes: 2