从 etree 中删除一个节点但留下子节点

cca*_*cho 2 python xml elementtree

我遍历了一个 XML 树,并且通过从树中提取一个节点而留下了它们的内部节点而遇到了一些麻烦。

例如:

<xml>
    <letter name="B">
        <letter name="D">
            <letter name="E">
                <letter name="F">
                    <letter name="G">

                    </letter>
                </letter>
            </letter>
        </letter>
    </letter>
</xml>
Run Code Online (Sandbox Code Playgroud)

我需要这样的东西:

<xml>
    <letter name="B">
        <letter name="D">
                <letter name="F">
                    <letter name="G">

                    </letter>
                </letter>
        </letter>
    </letter>
</xml>
Run Code Online (Sandbox Code Playgroud)

但是如果不移除所有的 E 孩子,我就无法得到这个。

干杯!

ale*_*cxe 5

这个想法是找到letter与元素name="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)
Run Code Online (Sandbox Code Playgroud)

它打印:

<xml>
    <letter name="B">
        <letter name="D">
            <letter name="F">
                    <letter name="G">

                    </letter>
                </letter>
            </letter>
    </letter>
</xml>
Run Code Online (Sandbox Code Playgroud)

UPD(使用迭代方法):

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)
Run Code Online (Sandbox Code Playgroud)

iterparent()功能取自Accessing Parents文档中的段落。