Bhaskar Bhuyan
Bhaskar Bhuyan

Reputation: 581

Adding child element to XML in python

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

Answers (1)

brokkr
brokkr

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

Related Questions