Mueve un elemento entero con lxml.etree

Dentro de lxml, ¿es posible, dado un elemento, mover todo el contenido a otro lugar en el documento xml sin tener que leer todos sus hijos y recrearlo? Mi mejor ejemplo sería cambiar a los padres. Revolví un poco los documentos pero no tuve mucha suerte. ¡Gracias por adelantado!

.append , .insert y otras operaciones hacen eso por defecto

 >>> from lxml import etree >>> tree = etree.XML('') >>> node_b = tree.xpath('/a/b')[0] >>> node_d = tree.xpath('/a/d')[0] >>> node_d.append(node_b) >>> etree.tostring(tree) # complete 'b'-branch is now under 'd', after 'e' '' >>> node_f = tree.xpath('/a/d/e/f')[0] # Nothing stops us from moving it again >>> node_f.append(node_a) # Now 'a' is deep under 'f' >>> etree.tostring(tree) '' 

Tenga cuidado al mover los nodos que tienen un texto de cola. En lxml el texto de la cola pertenece al nodo y se mueve con él. (Además, cuando elimina un nodo, también se elimina el texto de la cola)

 >>> tree = etree.XML('TAIL') >>> node_b = tree.xpath('/a/b')[0] >>> node_d = tree.xpath('/a/d')[0] >>> node_d.append(node_b) >>> etree.tostring(tree) 'TAIL' 

A veces es un efecto deseado, pero a veces necesitarás algo así:

 >>> tree = etree.XML('TAIL') >>> node_b = tree.xpath('/a/b')[0] >>> node_d = tree.xpath('/a/d')[0] >>> node_a = tree.xpath('/a')[0] >>> # Manually move text >>> node_a.text = node_b.tail >>> node_b.tail = None >>> node_d.append(node_b) >>> etree.tostring(tree) >>> # Now TAIL text stays within its old place 'TAIL' 

Podría usar los .append() , .insert() para agregar un subelemento al elemento existente:

 >>> from lxml import etree >>> from_ = etree.fromstring("") >>> to = etree.fromstring("") >>> to.append(from_) >>> etree.tostring(to) ''