2015-05-07 47 views
3

Python代碼:ElementTree的 - 的FindAll以遞歸方式選擇所有子元素

import xml.etree.ElementTree as ET 
root = ET.parse("h.xml") 
print root.findall('saybye') 

h.xml代碼:

<hello> 
    <saybye> 
    <saybye> 
    </saybye> 
    </saybye> 
    <saybye> 
    </saybye> 
</hello> 

代碼輸出,

[<Element 'saybye' at 0x7fdbcbbec690>, <Element 'saybye' at 0x7fdbcbbec790>] 

saybye它是的子此處未選擇另一個saybye。那麼,如何指示findall以遞歸方式遍歷DOM樹並收集所有三個saybye元素?

回答

2

引用findall

Element.findall()發現僅與一標籤,其是當前元素的直接子元素。

因爲它只能找到直接的孩子,我們需要遞歸地找到其他的孩子,像這樣

>>> import xml.etree.ElementTree as ET 
>>> 
>>> def find_rec(node, element, result): 
...  for item in node.findall(element): 
...   result.append(item) 
...   find_rec(item, element, result) 
...  return result 
... 
>>> find_rec(ET.parse("h.xml"), 'saybye', []) 
[<Element 'saybye' at 0x7f4fce206710>, <Element 'saybye' at 0x7f4fce206750>, <Element 'saybye' at 0x7f4fce2067d0>] 

更妙的是,使發電機的功能,這樣

>>> def find_rec(node, element): 
...  for item in node.findall(element): 
...   yield item 
...   for child in find_rec(item, element): 
...    yield child 
... 
>>> list(find_rec(ET.parse("h.xml"), 'saybye')) 
[<Element 'saybye' at 0x7f4fce206a50>, <Element 'saybye' at 0x7f4fce206ad0>, <Element 'saybye' at 0x7f4fce206b10>] 
0

Element.findall()僅查找具有當前元素的直接子元素的標籤。

我們需要遞歸遍歷所有孩子以找到與您的元素匹配的元素。

def find_rec(node, element): 
    def _find_rec(node, element, result): 
     for el in node.getchildren(): 
      _find_rec(el, element, result) 
     if node.tag == element: 
      result.append(node) 
    res = list() 
    _find_rec(node, element, res) 
    return res 
相關問題