【问题标题】:Removing parent element and all subelements from XML从 XML 中删除父元素和所有子元素
【发布时间】:2014-11-18 07:24:12
【问题描述】:

给定一个具有以下结构的 XML 文件:

<Root>
    <Stuff></Stuff>
    <MoreStuff></MoreStuff>
    <Targets>
        <Target>
            <ID>12345</ID>
            <Type>Ground</Type>
            <Size>Large</Size>
        </Target>
        <Target>
            ...
        </Target>
    </Targets>
</Root>

我正在尝试遍历&lt;Targets&gt; 元素下的每个子元素,检查每个&lt;ID&gt; 的特定值,如果找到该值,那么我想删除整个&lt;Target&gt; 条目。我一直在使用 ElementTree Python 库,但收效甚微。这是我目前所拥有的:

import xml.etree.ElementTree as ET

tree = ET.parse('file.xml')
root = tree.getroot()

iterator = root.getiterator('Target')

for item in iterator:
    old = item.find('ID')
    text = old.text
    if '12345' in text:
        item.remove(old)

tree.write('out.xml')

我在使用这种方法时遇到的问题是仅删除了 &lt;ID&gt; 子元素,但是我需要删除整个 &lt;Target&gt; 元素及其所有子元素。谁能帮忙!谢谢。

【问题讨论】:

    标签: python xml python-2.7 elementtree


    【解决方案1】:

    不幸的是,元素树元素不知道他们的父母是谁。有一个解决方法——You can build the mapping yourself:

    tree = ET.parse('file.xml')
    root = tree.getroot()
    parent_map = dict((c, p) for p in tree.getiterator() for c in p)
    
    # list so that we don't mess up the order of iteration when removing items.
    iterator = list(root.getiterator('Target'))
    
    for item in iterator:
        old = item.find('ID')
        text = old.text
        if '12345' in text:
            parent_map[item].remove(item)
            continue
    
    tree.write('out.xml')
    

    未经测试

    【讨论】:

    • +1,即使它未经测试,因为它可能有效,或者如果无效,至少是解决方案的 99%。
    【解决方案2】:

    您需要保留对 Targets 元素的引用,以便删除它的子元素,因此从那里开始您的迭代。抓住每个目标,检查你的状况并移除你不喜欢的东西。

    #!/usr/bin/env python
    import xml.etree.ElementTree as ET
    
    xmlstr="""<Root>
        <Stuff></Stuff>
        <MoreStuff></MoreStuff>
        <Targets>
            <Target>
                <ID>12345</ID>
                <Type>Ground</Type>
                <Size>Large</Size>
            </Target>
            <Target>
                ...
            </Target>
        </Targets>
    </Root>"""
    
    root = ET.fromstring(xmlstr)
    
    targets = root.find('Targets')
    
    for target in targets.findall('Target'):
        _id = target.find('ID')
        if _id is not None and '12345' in _id.text:
            targets.remove(target)
    
    print ET.tostring(root)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-01-17
      • 2012-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-14
      • 1970-01-01
      相关资源
      最近更新 更多