2014-09-23 123 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)