Reputation: 581
I have an element in an XML file as:
<condition>
<comparison compare="and">
<operand idref="XXX" type="boolean" />
</comparison>
</condition>
I need to add two other child elements (child1 and child2) such as:
<condition>
<child1 compare='and'>
<child2 idref='False' type='int' />
<comparison compare="and">
<operand idref="XXX" type="boolean" />
</comparison>
</child1>
</condition>
I proceeded using lxml:
from lxml import etree
tree = etree.parse(xml_file)
condition_elem = tree.find("<path for the condition block in the xml>")
etree.SubElement(condition_elem, 'child1')
tree.write( 'newXML.xml', encoding='utf-8', xml_declaration=True)
This just adds the element child1 as a child of the element condition as below and did not satisfy my requirement:
<condition>
<child1></child1>
<comparison compare="and">
<operand idref="XXX" type="boolean" />
</comparison>
</condition>
Any ideas? Thanks
Upvotes: 1
Views: 4457
Reputation: 3051
Using lxml's objectify submodule over it's etree submodule, I would cut out the comparison element from root, add the child1 element to it and the stuff comparison back in to that:
from lxml import objectify
tree = objectify.parse(xml_file)
condition = tree.getroot()
comparison = condition.comparison
M = objectify.ElementMaker(annotate=False)
child1 = M("child1", {'compare': 'and'})
child2 = M("child2", {'idref': 'False', 'type': 'int'})
condition.remove(comparison)
condition.child1 = child1
condition.child2 = child2
condition.child1.comparison = comparison
The ElementMaker is an easy-to-use tool to create new xml elements. I first an instance of it (M) that doesn't annotate the xml (litter it with attributes), then use that instance to create the children, you ask for. The rest is fairly self explanatory, I think.
Upvotes: 1