在Python ElementTree中,如何获取树中元素的所有祖先的列表?

时间:2010-06-14 22:00:59

标签: python xml tree elementtree

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

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

有人可以帮我吗?

3 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:1)

在最新版本的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,并为垃圾收集创建了很多列表,但是如果你可以处理它应该没问题。

答案 2 :(得分:0)

通过大量的Google搜索(http://elmpowered.skawaii.net/?p=74

找到了这个小宝石

parent = root.findall(“.// {0} / ..”。format(elem.tag))

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

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