【问题标题】:XML remove nodes with no attributes or childrenXML 删除没有属性或子节点的节点
【发布时间】:2016-07-20 17:26:57
【问题描述】:

我加载了一个 xml 文件,我想从中删除没有属性或子级的元素,我正在尝试实现这样的目标:

for child in root.find('targetElement'):
    print(child)
    if(len(child.attrib) < 1 and len(child) < 1):
        root.remove(child)

但我想问题是我正在找到该元素,然后尝试将其从根元素中删除。有人可以告诉我怎么做吗?

【问题讨论】:

    标签: python xml python-3.x elementtree xml.etree


    【解决方案1】:

    您需要从其父节点中删除一个节点,而不是从根节点。

    以下代码适用于lxml.etree

    from lxml import etree as ET
    
    root = ET.parse('yourfile.xml')
    
    for child in root.iterfind('targetElement'):
        if(len(child.attrib) < 1 and len(child) < 1):
            child.getparent().remove(child)
    

    标准xml.etree.ElementTree 缺少任何合适的选择父节点的方法。我们可以通过为整个树构建一个子到父映射来解决这个限制 (source):

    import xml.etree.ElementTree as ET
    
    root = ET.parse('yourfile.xml')
    
    # https://stackoverflow.com/a/20132342/18771
    parent_map = {c:p for p in root.iter() for c in p}
    
    for child in root.iterfind('targetElement'):
        if(len(child.attrib) < 1 and len(child) < 1):
            parent_map[child].remove(child)
    

    【讨论】:

    • 对不起,我错过了什么? AttributeError: 'xml.etree.ElementTree.Element' 对象没有属性 'getparent'
    • getparent() 在 lxml 中可用,但在标准库 ElementTree 模块中不可用。
    • @mao 我明白了。试试child.findall('..')[0].remove(child)
    • 谢谢,但另一个问题 child.findall('..')[0].remove(child) IndexError: list index out of range
    • @mao 似乎对在 elementtree 中选择父节点的支持比我想象的要坏。查看修改后的答案。另请注意,我使用iterfind() 而不是find()
    猜你喜欢
    • 1970-01-01
    • 2011-02-09
    • 2013-02-04
    • 1970-01-01
    • 2018-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多