使用lxml.etree移动整个元素

时间:2012-01-26 00:14:00

标签: python xml lxml

在lxml中,在给定元素的情况下,是否有可能将整个内容移动到xml文档中的其他位置,而无需读取所有子项并重新创建它?我最好的例子就是改变父母。我有点翻遍文档,但运气不好。提前谢谢!

2 个答案:

答案 0 :(得分:18)

.append.insert和其他操作默认执行此操作

>>> from lxml import etree
>>> tree = etree.XML('<a><b><c/></b><d><e><f/></e></d></a>')
>>> 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'
'<a><d><e><f/></e><b><c/></b></d></a>'
>>> 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)
'<a><d><e><f><b><c/></b></f></e></d></a>'

移动具有尾部文本的节点时要小心。在lxml尾部文本属于节点并随之移动。 (另外,删除节点时,其尾部文本也会被删除)

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

有时这是一种理想的效果,但有时你需要这样的东西:

>>> tree = etree.XML('<a><b><c/></b>TAIL<d><e><f/></e></d></a>')
>>> 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
'<a>TAIL<d><e><f/></e><b><c/></b></d></a>'

答案 1 :(得分:0)

您可以使用.append().insert()方法向现有元素添加子元素:

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