2010-10-23 11 views
24

Come clonare Element oggetti in Python ? Sto provando a spostare e copiare proceduralmente (quindi modificare i loro attributi) nodi.etree Clone Node

risposta

30

È possibile utilizzare solo copy.deepcopy() per creare una copia dell'elemento. (questo funzionerà anche con lxml).

+4

Questo fa una copia, ma non viene aggiunta all'albero. Dovrai fare un 'append()' o 'insert()' per farlo. –

+0

tra l'altro anche per cElementTree ;-) – Thierry

0

Se si dispone di una maniglia su s' parent il Elementelem è possibile chiamare

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

In caso contrario si potrebbe desiderare di provare

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

ma questo non è consigliato.

+2

penso che non copiano i nodi figlio .. –

+0

@SHiNKiROU Puoi confrontare 'id (old_element)' con 'id (new_element)' per vedere se crea effettivamente un oggetto diverso in memoria. questo aiuta? –

+0

Come menziona @ Ming-Tang, questo ** non ** copia i bambini. – halloleo

3

Una diversa soluzione, e piuttosto disturbante:

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

Almeno in Python 2.7 eTree elemento ha un metodo di copia: http://hg.python.org/cpython/file/2.7/Lib/xml/etree/ElementTree.py#l233

È una copia, ma che è preferibile in alcuni casi .

Nel mio caso sto duplicando alcuni elementi SVG e aggiungendo una trasformazione. Duplicare i bambini non servirebbe a nessuno scopo poiché, se pertinente, già ereditano la trasformazione dei loro genitori.

+3

Per chi usa questo e pensa di sostituire * xml.etree.ElementTree * con * lxml.etree * in futuro, si noti che 'Element.copy()' non esiste in * lxml.etree *, e 'copy.copy()' copia anche i bambini, se applicati a 'lxml.etree.Element'. – meowsqueak

+0

Non funziona con cElementTree (Python 2.7). Quindi preferisci copy.copy() (copia superficiale) o copy.deepcopy() per l'evolutività del codice. – Thierry

-1

Per riferimento futuro.

più semplice modo per copiare un nodo (o albero) e tenerlo per bambini, senza dover importare ALTRO biblioteca SOLO per questo:

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

Per essere chiari, questa non è una copia profonda. (Sì, il post dice "e mantieni i suoi figli", ma sentivo ancora il bisogno di testare cosa significasse). – harpo