python xml 删除孙子或孙子

python xml remove grandchildren or grandgrandchildren

我一直在谷歌搜索以从 xml 文件中删除孙子。但是,我没有找到完美的解决方案。 这是我的案例:

<tree>
    <category title="Item 1">item 1 text
        <subitem title="subitem1">subitem1 text</subitem>
        <subitem title="subitem2">subitem2 text</subitem>
    </category>

    <category title="Item 2">item 2 text
        <subitem title="subitem21">subitem21 text</subitem>
        <subitem title="subitem22">subitem22 text</subitem>
            <subsubitem title="subsubitem211">subsubitem211 text</subsubitem>
    </category>
</tree>

在某些情况下,我想删除 subitems。在其他情况下,我想删除 subsubitem。我知道我可以在当前给定的内容中这样做:

import xml.etree.ElementTree as ET

root = ET.fromstring(given_content)
# case 1
for item in root.getiterator():
    for subitem in item:
        item.remove(subitem)

# case 2
for item in root.getiterator():
    for subitem in item:
        for subsubitem in subitem:
            subitem.remove(subsubitem)

只有当我知道目标节点的深度时,我才能这样写。如果我只知道要移除的节点的标签名,应该如何实现呢? 伪代码:

import xml.etree.ElementTree as ET

for item in root.getiterator():
    if item.tag == 'subsubitem' or item.tag == 'subitem':
        # remove item

如果我做 root.remove(item),它肯定会 return 一个错误,因为项目不是 root 的直接子项。

已编辑: 我无法安装任何 3rd-party-lib,所以我必须用 xml.

来解决这个问题

要删除 subsubitemsubitem 的实例,无论它们的深度如何,请考虑以下示例(注意它使用 lxml.etree 而不是上游 ElementTree):

import lxml.etree as etree

el = etree.fromstring('<root><item><subitem><subsubitem/></subitem></item></root>')
for child in el.xpath('.//subsubitem | .//subitem'):
  child.getparent().remove(child)

我终于通过编写递归函数在 xml lib 上完成了这项工作。

def recursive_xml(root):
    if root.getchildren() is not None:
        for child in root.getchildren():
            if child.tag == 'subitem' or child.tag == 'subsubitem':
                root.remove(child)
            else:
                recursive_xml(child)

通过这样做,该函数将迭代 ET 中的每个节点并删除我的目标节点。

test_xml = r'''
<test>
    <test1>
        <test2>
            <test3>
            </test3>
            <subsubitem>
            </subsubitem>
        </test2>
        <subitem>
        </subitem>
        <nothing_matters>
        </nothing_matters>
    </test1>
</test>
'''
root = ET.fromstring(test_xml)
recursive_xml(root)

希望这对像我这样有限制要求的人有帮助....