【问题标题】:Remove element siblings from etree in python从python中的etree中删除元素兄弟
【发布时间】:2014-05-13 18:27:25
【问题描述】:

我试图删除给定元素的所有兄弟:

例如,给定这个 etree 对象

<xml>
    <letter name="A">
            <letter name="B">
                    <letter name="C">
                    </letter>
                    <letter name="D">
                    </letter>
                    <letter name="G">
                    </letter>
                    <letter name="H">
                    </letter>
                    <letter name="I">
                    </letter>
            </letter>
            <letter name="E">
                <letter name="F">
                </letter>
            </letter>
    </letter>
</xml>

我想删除所有 G 节点兄弟并返回:

<xml>
    <letter name="A">
            <letter name="B">
                    <letter name="G">
                    </letter>
            </letter>
            <letter name="E">
                <letter name="F">
                </letter>
            </letter>
    </letter>
</xml>

不使用 xpath 或 find,以迭代方式。

你能提供一些建议吗?

这是我刚刚写的代码

import xml.etree.ElementTree as etree
data = """

<xml>
    <letter name="A">
            <letter name="B">
                    <letter name="C">
                    </letter>
                    <letter name="D">
                    </letter>
                    <letter name="G">
                    </letter>
                    <letter name="H">
                    </letter>
                    <letter name="I">
                    </letter>
            </letter>
            <letter name="E">
                <letter name="F">
                </letter>
            </letter>
    </letter>
</xml>

"""
tree =etree.fromstring(data)


for parent in tree.getiterator():
    for child in parent:
        for subchild in child:
            if subchild.attrib.get('name') == "G":
                parent_name = child.attrib.get('name')
                #print parent_name

for parent in tree.getiterator():
    if parent.attrib.get('name') == parent_name:
        for child in parent:
            if child.attrib.get('name') == "G":
                print "not this"
            else:
                parent.remove(child)


print etree.tostring(tree)

干杯!

【问题讨论】:

  • 你能分享你已经尝试过的任何代码吗?
  • 不使用xpath?为什么?
  • 任何帮助@JustinBarber??
  • @Charlie 抱歉耽搁了。感谢您更新您的问题。请参阅下面的答案。

标签: python xml elementtree xml.etree


【解决方案1】:

你很接近。一旦找到名称G,您将需要通过包含名称G 的任何元素重复。因此,您将希望在这些方面使用更多的东西(根据您的要求,它使用迭代而不是 xpath 或 find):

>>> def remove(name, value, root):
    """
    Iterates through the @root element and removes elements
    where the @name != @value.
    """
    for element in root:
        if element.attrib.get(name) != value:
            root.remove(element)


>>> def remove_siblings_of(name, value, root):
    """
    Recursively removes from the @root element all elements which (1) do
    not have @name == @value but (2) do have a sibling where @name == @value.
    """
    for element in root:
        if element.attrib.get(name) == value:
            remove(name, value, root)  # need to reiterate through element now to remove previous siblings
        if len(element):
            remove_siblings_of(name, value, element)
    return root

当你在你的 xml 上使用后一个函数时,你会得到你正在寻找的结果:

>>> siblings_removed = remove_siblings_of('name', 'G', root)
>>> print et.tostring(siblings_removed)
<xml>
    <letter name="A">
            <letter name="B">
                    <letter name="G">
                    </letter>
                    </letter>
            <letter name="E">
                <letter name="F">
                </letter>
            </letter>
    </letter>
</xml>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多