从etree中移除节点但保留子节点
我正在遍历一个XML树,但在提取树中的一个节点时遇到了一些麻烦,想要保留它里面的子节点。
举个例子:
<xml>
<letter name="B">
<letter name="D">
<letter name="E">
<letter name="F">
<letter name="G">
</letter>
</letter>
</letter>
</letter>
</letter>
</xml>
我需要的结果是这样的:
<xml>
<letter name="B">
<letter name="D">
<letter name="F">
<letter name="G">
</letter>
</letter>
</letter>
</letter>
</xml>
但是我无法做到这一点,因为这样会把所有的E子节点都删掉。
谢谢!
3 个回答
0
我刚刚完成这个任务,我只需要在删除之前复制一份树结构,不然原来的对象会被修改。
这是解决方案。顺便说一下,非常感谢!!!!XD
def remove_letter(tree_original, letter):
tree= copy.deepcopy(tree_original)
for parent in tree.getiterator():
for child in parent:
if child.attrib.get('name') == letter:
parent.remove(child)
parent.extend(child)
print etree.tostring(parent)
return parent
def get_next_trees(tree):
my_trees = []
for parent in tree.getiterator():
if child.attrib.get('name') == "D":
for child in parent:
my_trees.append(remove_letter(tree)
return my_trees
0
还有一件事,
这样做可能吗??
最初的XML内容是
<xml>
<letter name="B">
<letter name="D">
<letter name="E">
<letter name="F">
<letter name="G">
</letter>
</letter>
</letter>
<letter name="H">
<letter name="I">
</letter>
</letter>
</letter>
</letter>
</xml>
然后希望输出是一个包含两个树的列表,像这样:
<xml>
<letter name="B">
<letter name="E">
<letter name="F">
<letter name="G">
</letter>
</letter>
</letter>
</letter>
</xml>
<xml>
<letter name="B">
<letter name="H">
<letter name="I">
</letter>
</letter>
</letter>
</xml>
你们可以看到,@falsetru 和 @alecxe,我只是删除了D,只保留了每棵树的一个孩子。
谢谢!!!!
5
这个想法是找到一个名为 letter
的元素,它的名字是 "E",然后获取它的父元素,接着从父元素中移除这个元素,最后把这个元素的孩子们添加到父元素中:
import xml.etree.ElementTree as etree
data = """
<xml>
<letter name="B">
<letter name="D">
<letter name="E">
<letter name="F">
<letter name="G">
</letter>
</letter>
</letter>
</letter>
</letter>
</xml>
"""
XPATH = './/letter[@name="E"]'
tree = etree.fromstring(data)
letter = tree.find(XPATH)
parent = tree.find(XPATH + '/..')
parent.remove(letter)
parent.extend(letter)
print etree.tostring(tree)
它会打印出:
<xml>
<letter name="B">
<letter name="D">
<letter name="F">
<letter name="G">
</letter>
</letter>
</letter>
</letter>
</xml>
更新(使用迭代的方法):
def iterparent(tree):
for parent in tree.getiterator():
for child in parent:
yield parent, child
tree = etree.fromstring(data)
for parent, child in iterparent(tree):
if child.tag == "letter" and child.attrib.get('name') == "E":
parent.remove(child)
parent.extend(child)
print etree.tostring(tree)
iterparent()
函数是从文档中的 访问父元素
这一段中获取的。