ElementTree - findall to recursively select all child elements

前端 未结 4 1100
情歌与酒
情歌与酒 2020-12-06 18:46

Python code:

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

h.xml code:



        
相关标签:
4条回答
  • 2020-12-06 19:28

    Element.findall() finds only elements with a tag which are direct children of the current element.

    we need to recursively traversing all childrens to find elements matching your element.

    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
    
    0 讨论(0)
  • 2020-12-06 19:33

    Quoting findall,

    Element.findall() finds only elements with a tag which are direct children of the current element.

    Since it finds only the direct children, we need to recursively find other children, like this

    >>> 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>]
    

    Even better, make it a generator function, like this

    >>> 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 讨论(0)
  • 2020-12-06 19:35

    From version 2.7 on, you can use xml.etree.ElementTree.Element.iter:

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

    See 19.7. xml.etree.ElementTree — The ElementTree XML API

    0 讨论(0)
  • 2020-12-06 19:44

    If you aren't afraid of a little XPath, you can use the // syntax that means find any descendant node:

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

    Full XPath isn't supported, but here's the list of what is: https://docs.python.org/2/library/xml.etree.elementtree.html#supported-xpath-syntax

    0 讨论(0)
提交回复
热议问题