2014-05-13 60 views
0

進出口試圖除去所有兄弟姐妹給定的元素:刪除元素的兄弟姐妹在python

例如,給定此etree對象

<xml> 
    <letter name="A"> 
      <letter name="B"> 
        <letter name="C"> 
        </letter> 
        <letter name="D"> 
        </letter> 
        <letter name="G"> 
        </letter> 
        <letter name="H"> 
        </letter> 
        <letter name="I"> 
        </letter> 
      </letter> 
      <letter name="E"> 
       <letter name="F"> 
       </letter> 
      </letter> 
    </letter> 
</xml> 

我想刪除全部G節點的兄弟姐妹和返回此:

<xml> 
    <letter name="A"> 
      <letter name="B"> 
        <letter name="G"> 
        </letter> 
      </letter> 
      <letter name="E"> 
       <letter name="F"> 
       </letter> 
      </letter> 
    </letter> 
</xml> 

不使用xpath或找到,以迭代的方式。

你能提供一些關於如何做的建議嗎?

這是我只寫

import xml.etree.ElementTree as etree 
data = """ 

<xml> 
    <letter name="A"> 
      <letter name="B"> 
        <letter name="C"> 
        </letter> 
        <letter name="D"> 
        </letter> 
        <letter name="G"> 
        </letter> 
        <letter name="H"> 
        </letter> 
        <letter name="I"> 
        </letter> 
      </letter> 
      <letter name="E"> 
       <letter name="F"> 
       </letter> 
      </letter> 
    </letter> 
</xml> 

""" 
tree =etree.fromstring(data) 


for parent in tree.getiterator(): 
    for child in parent: 
     for subchild in child: 
      if subchild.attrib.get('name') == "G": 
       parent_name = child.attrib.get('name') 
       #print parent_name 

for parent in tree.getiterator(): 
    if parent.attrib.get('name') == parent_name: 
     for child in parent: 
      if child.attrib.get('name') == "G": 
       print "not this" 
      else: 
       parent.remove(child) 


print etree.tostring(tree) 

乾杯代碼!

+0

你可以分享你已經嘗試過的任何代碼嗎? –

+1

不使用xpath?爲什麼? – roippi

+0

任何幫助@JustinBarber ?? – ccamacho

回答

1

你就近了。一旦找到名稱G,您將需要重複通過任何包含名稱G的元素。所以,你將要使用這些方針的東西更多的(它使用迭代,而不是XPath或查找,根據您的要求):當你用你的XML後者功能

>>> def remove(name, value, root): 
    """ 
    Iterates through the @root element and removes elements 
    where the @name != @value. 
    """ 
    for element in root: 
     if element.attrib.get(name) != value: 
      root.remove(element) 


>>> def remove_siblings_of(name, value, root): 
    """ 
    Recursively removes from the @root element all elements which (1) do 
    not have @name == @value but (2) do have a sibling where @name == @value. 
    """ 
    for element in root: 
     if element.attrib.get(name) == value: 
      remove(name, value, root) # need to reiterate through element now to remove previous siblings 
     if len(element): 
      remove_siblings_of(name, value, element) 
    return root 

,你會得到的結果你尋找:

>>> siblings_removed = remove_siblings_of('name', 'G', root) 
>>> print et.tostring(siblings_removed) 
<xml> 
    <letter name="A"> 
      <letter name="B"> 
        <letter name="G"> 
        </letter> 
        </letter> 
      <letter name="E"> 
       <letter name="F"> 
       </letter> 
      </letter> 
    </letter> 
</xml> 
+0

謝謝!這工作正常! – ccamacho