2014-09-23 160 views
2

所有子元素考虑用以下结构的XML文件:删除父元素和XML

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

我通过<Targets>元素下每个孩子尝试循环,检查各<ID>特定值,如果找到该值,那么我想删除整个<Target>条目。我一直在使用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') 

我用这种方法遇到的问题是,只有<ID>子元素被删除,但是我需要整个<Target>元素,除了所有的子元素。谁能帮忙!谢谢。

回答

6

不幸的是,元素树元素不知道他们的父母是谁。有一种变通方法 - 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') 

未经测试

+0

+1即使未经测试,因为它可能有效,或者至少99%的解决方案,如果它没有。 – synthesizerpatel 2014-09-23 23:33:26

2

你需要保持对目标元素的引用,这样就可以删除它的孩子,所以,从那里开始您的迭代。抓住每个目标,检查你的情况,并删除你不喜欢的东西。

#!/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)