2010-10-23 11 views
24

Cómo clonar Element objetos en Python xml.etree? Estoy intentando mover y copiar (luego modificar sus atributos) los nodos procesales.etree Nodo de clon

Respuesta

30

Puede simplemente usar copy.deepcopy() para hacer una copia del elemento. (Esto también funcionará con lxml por cierto).

+4

Eso hace una copia, pero no se agrega al árbol. Tendrá que hacer un 'append()' o 'insert()' para hacer eso. –

+0

esto también funciona con cElementTree por cierto ;-) – Thierry

0

Si usted tiene una manija en el Elementelem 's parent puede llamar

new_element = SubElement(parent, elem.tag, elem.attrib) 

lo contrario puede que desee probar

new_element = makeelement(elem.tag, elem.attrib) 

pero esto no es recomendable.

+2

Creo que no copian los nodos secundarios .. –

+0

@SHiNKiROU Puede comparar 'id (old_element)' con 'id (new_element)' para ver si realmente crea un objeto diferente en la memoria. ¿Esto ayuda? –

+0

Como menciona @ Ming-Tang, este ** no ** copia a los niños. – halloleo

3

Una solución diferente, y algo preocupante:

new_element = lxml.etree.fromstring(lxml.etree.tostring(elem)) 
1

Al menos en Python 2.7 etree elemento tiene un método de copia: http://hg.python.org/cpython/file/2.7/Lib/xml/etree/ElementTree.py#l233

Es una copia superficial, pero que es preferible en algunos casos .

En mi caso, estoy duplicando algunos elementos SVG y agregando una transformación. La duplicación de los niños no serviría para nada, ya que, cuando sea relevante, ya heredan la transformación de sus padres.

+3

Para cualquiera que use esto y piense en reemplazar * xml.etree.ElementTree * con * lxml.etree * en el futuro, tenga en cuenta que 'Element.copy()' no existe en * lxml.etree *, y 'copy.copy()' también copia hijos cuando se aplica a un 'lxml.etree.Element'. – meowsqueak

+0

No funciona con cElementTree (Python 2.7). Por lo tanto, prefiero copy.copy() (copia superficial) o copy.deepcopy() para la evolutividad del código. – Thierry

-1

Para referencia futura.

forma más sencilla de copiar un nodo (o árbol) y mantenerlo infantil, sin tener que importar OTRO biblioteca SOLO para ello:

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

Para ser claros, esta no es una copia profunda. (Sí, la publicación dice "y conserve a sus hijos", pero todavía sentía la necesidad de probar lo que significaba). – harpo