The following is extracted from the lxml documentation
Note that in the original ElementTree, a single Element object can sit
in any number of places in any number of trees, which allows for the
same copy operation as with lists. The obvious drawback is that
modifications to such an Element will apply to all places where it
appears in a tree, which may or may not be intended.
The upside of this difference is that an Element in lxml.etree always
has exactly one parent, which can be queried through the getparent()
method. This is not supported in the original ElementTree.
So an element in lxml can only have one parent unlike the original element from ElementTree. So its not possible to just append the same element to more than one parent using lxml. However the documentation suggests to handle this new design you should use deep copy to copy the element you want to append to another element if its already assigned somewhere.
This will create a new copy of the element and as such the new copy can be assigned to a different parent element. These are seperate copy's so changing one will not change the other.
from lxml import etree
from copy import deepcopy
top = etree.Element('Primary')
element1 = etree.Element('Secondary')
element2 = etree.Element('Secondary')
details = etree.Element('Details', somevalue='value')
element1.append(details)
element2.append(deepcopy(details))
top.append(element1)
top.append(element2)
print(etree.tostring(top, encoding="unicode", pretty_print=True))
OUTPUT
<Primary>
<Secondary>
<Details somevalue="value"/>
</Secondary>
<Secondary>
<Details somevalue="value"/>
</Secondary>
</Primary>
Updated with example for Jack
So in thie example Jack i set a variable num_secondarys that will create X secondary elements each with a details element and the values in the detail element will incrmement by 1. I create a single element of secondary and detail as a template, then use deepcopy to copy them as new elements.
from lxml import etree
from copy import deepcopy
top = etree.Element('Primary')
secondary = etree.Element('Secondary')
detail = etree.Element('Details', somevalue='value')
num_secondarys = 3
for i in range(1, num_secondarys + 1):
this_secondary = deepcopy(secondary)
this_detail = deepcopy(detail)
this_detail.attrib['somevalue']+=str(i)
this_secondary.append(this_detail)
top.append(this_secondary)
print(etree.tostring(top, encoding="unicode", pretty_print=True))
OUTPUT
<Primary>
<Secondary>
<Details somevalue="value1"/>
</Secondary>
<Secondary>
<Details somevalue="value2"/>
</Secondary>
<Secondary>
<Details somevalue="value3"/>
</Secondary>
</Primary>