Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Insert a tree under another tree (lxml)

Tags:

python

xml

lxml

I need to insert the whole contents of one XML tree into another tree (under its elements with a certain tag). I'm using the iter() method to iterate over the elements of the tree to be modified. The problem is, the first tree only gets inserted once for some reason.

Could anyone tell me what I'm doing wrong?

from lxml import etree

# Creating the first tree
root1 = etree.Element('root', name = 'Root number one')
tree1 = etree.ElementTree(root1)

for n in range(1, 5):
    new_element = etree.SubElement(root1, 'element' + str(n))
    new_child = etree.Element('child')
    new_child.text = 'Test' + str(n)
    new_element.insert(0, new_child)

# Creating the second tree
root2 = etree.Element('root', name = 'Root number two')
tree2 = etree.ElementTree(root2)

for n in range(1, 3):
    new_element = etree.SubElement(root2, 'element')
    new_child = etree.Element('child')
    new_child.text = 'Test' + str(n)
    new_element.insert(0, new_child)

# Printing the trees to files to see what they look like
outFile1 = open('file1.xml', 'w')
print(etree.tostring(tree1, encoding='unicode', pretty_print=True), file=outFile1)

outFile2 = open('file2.xml', 'w')
print(etree.tostring(tree2, encoding='unicode', pretty_print=True), file=outFile2)

# Here I'm using the iter() method to iterate over the elements of tree2
# Under each element tagged as "element" I need to insert the whole contents
# of tree1
for element in tree2.iter():
    if element.tag == 'element':
        new_child = tree1.getroot()
        element.insert(0, new_child)

outFile3 = open('file3.xml', 'w')
print(etree.tostring(tree2, encoding='unicode', pretty_print=True), file=outFile3)
like image 715
Andy K. Avatar asked Nov 27 '25 06:11

Andy K.


1 Answers

Quoth the lxml tutorial:

If you want to copy an element to a different position in lxml.etree, consider creating an independent deep copy using the copy module from Python's standard library.

So, in your example,

for element in tree2.iter():
    if element.tag == 'element':
        new_child = copy.deepcopy(tree1.getroot())
        element.insert(0, new_child)
like image 91
Robᵩ Avatar answered Nov 28 '25 20:11

Robᵩ



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!