【问题标题】:In Python ElementTree how can I get list of all ancestors of an element in tree?在 Python ElementTree 中,如何获取树中元素的所有祖先的列表?
【发布时间】:2010-06-14 22:00:58
【问题描述】:

我需要“get_ancestors_recursively”函数。
样本运行可以是

>>> dump(tr)
<anc1>
  <anc2>
    <element> </element>
  </anc2>
</anc1>
>>> input_element = tr.getiterator("element")[0]
>>> get_ancestors_recursively(input_element)
['anc1', 'anc2']

有人可以帮我吗?

【问题讨论】:

    标签: python xml tree elementtree


    【解决方案1】:

    另一个选项是LXML,它为内置的 ElementTree api 提供了有用的扩展。如果你愿意安装一个外部模块,它有一个很好的Element.getparent() 函数,你可以简单地递归调用直到到达ElementTree.getroot()。这可能是最快和最优雅的解决方案(因为lxml.etree module 为指向其父元素的元素引入了指针属性,因此无需在整个树中搜索正确的parent/child 对)。

    【讨论】:

    • 是:使用lxml,然后可以递归调用elem.getparent()爬上树,也可以使用elem.xpath('ancestor::*')获取列表直接的祖先节点。 ( xpath 可以将任何节点用作上下文节点,而不仅仅是文档根。)
    【解决方案2】:

    在最新版本的ElementTree(v1.3或更高版本)中,您可以简单地做

    input_element.find('..')
    

    递归。但是,Python 附带的 ElementTree 没有这个功能,我在 Element 类中看不到任何向上的东西。

    我相信这意味着您必须以艰难的方式做到这一点:通过对元素树的详尽搜索。

    def get_ancestors_recursively(e, b):
        "Finds ancestors of b in the element tree e."
        return _get_ancestors_recursively(e.getroot(), b, [])
    
    def _get_ancestors_recursively(s, b, acc):
        "Recursive variant. acc is the built-up list of ancestors so far."
        if s == b:
            return acc
        else:
            for child in s.getchildren():
                newacc = acc[:]
                newacc.append(s)
                res = _get_ancestors_recursively(child, b, newacc)
                if res is not None:
                    return res
            return None
    

    由于 DFS,这很慢,并且会生成很多垃圾收集列表,但如果你能处理它应该没问题。

    【讨论】:

      【解决方案3】:

      从大量谷歌搜索中找到了这个小宝石 (http://elmpowered.skawaii.net/?p=74)

      parent = root.findall(".//{0}/..".format(elem.tag))

      root 这里是树的根节点。 elem 是您从迭代中获得的实际元素对象。

      这确实需要您知道根,这可能意味着更改您为 XML 解析设置的方式,但它充其量只是次要的。

      【讨论】:

        猜你喜欢
        • 2012-05-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-25
        • 1970-01-01
        • 1970-01-01
        • 2015-10-16
        • 2016-09-14
        相关资源
        最近更新 更多