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 元素?

原文由 user2879704 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 922
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>]

原文由 thefourtheye 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题