开发者

etree Clone Node

开发者 https://www.devze.com 2023-01-21 06:59 出处:网络
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

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
0

精彩评论

暂无评论...
验证码 换一张
取 消