etree Clone Node
How to clone Element
objects in Python xml.etree
? I'm trying to procedurally move and 开发者_Python百科copy (then modify their attributes) nodes.
You can just use copy.deepcopy() to make a copy of the element. (this will also work with lxml by the way).
A different, and somewhat disturbing solution:
new_element = lxml.etree.fromstring(lxml.etree.tostring(elem))
If you have a handle on the Element
elem
's parent
you can call
new_element = SubElement(parent, elem.tag, elem.attrib)
Otherwise you might want to try
new_element = makeelement(elem.tag, elem.attrib)
but this is not advised.
At least in Python 2.7 etree Element has a copy method: http://hg.python.org/cpython/file/2.7/Lib/xml/etree/ElementTree.py#l233
It is a shallow copy, but that is preferable in some cases.
In my case I am duplicating some SVG Elements and adding a transform. Duplicating children wouldn't serve any purpose since where relevant they already inherit their parent's transform.
If you procedurally move through your tree with loops, you can use insert
to clone directly ( insert(index, subelement)
) and tree indexing (both in the documentation):
import xml.etree.ElementTree as ET
mytree = ET.parse('some_xml_file.xml') # parse tree from xml file
root = mytree.getroot() # get the tree root
for elem in root: # iterate over children of root
if condition_for_cloning(elem) == True:
elem.insert(len(elem), elem[3]) # insert the 4th child of elem to the end of the element (clone an element)
or for children with some tag:
for elem in root:
children_of_interest = elem.findall("tag_of_element_to_clone")
elem.insert(len(elem), children_of_interest[1])
For anyone visiting from the future:
If you want to clone the entire element, use append
.
new_tree = ET.Element('root')
for elem in a_different_tree:
new_tree.append(elem)
@dennis-williamson made a comment about it which I overlooked and eventually stumbled on the answer here https://stackoverflow.com/a/6533808/4916945
For future reference.
Simplest way to copy a node (or tree) and keep it's children, without having to import ANOTHER library ONLY for that:
def copy_tree( tree_root ):
return et.ElementTree( tree_root );
duplicated_node_tree = copy_tree ( node ); # type(duplicated_node_tree) is ElementTree
duplicated_tree_root_element = new_tree.getroot(); # type(duplicated_tree_root_element) is Element
精彩评论