In Python ElementTree wie kann ich Liste aller Vorfahren eines Elements im Baum bekommen?

StackOverflow https://stackoverflow.com/questions/3041258

  •  27-09-2019
  •  | 
  •  

Frage

ich brauche "get_ancestors rekursiv" Funktion. Ein Probelauf kann sein

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

Kann jemand mir helfen mit diesem?

War es hilfreich?

Lösung

In der neuesten Version von ElementTree (v1.3 oder höher), können Sie einfach tun

input_element.find('..')

rekursiv. Allerdings ist die ElementTree, dass Schiffe mit Python nicht über diese Funktionalität, und ich habe nichts in der Element-Klasse sieht, dass Blicke nach oben.

Ich glaube, das heißt, Sie es auf die harte Art und Weise zu tun haben. Über eine erschöpfende Suche des Elements Baum

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

Dies ist langsam, da der DFS und Kurbeln aus einer Menge von Listen für die Garbage Collection, aber wenn man damit umgehen kann, sollte es in Ordnung sein.

Andere Tipps

Eine weitere Option ist LXML , die nützliche Erweiterungen für die in ElementTree api gebaut bietet. Wenn Sie bereit sind, ein externes Modul zu installieren, hat es eine schöne Element.getparent() Funktion, dass man einfach rekursiv bis zum Erreichen ElementTree.getroot() nennen könnte. Dies wird wahrscheinlich die schnellste und eleganteste Lösung (wie der lxml.etree module einleitet Zeiger für die Elemente Attribute, der Punkt zu ihren Eltern, so anstatt den gesamten Baum für die richtigen parent/child Paare suchen).

Wir haben dieses kleine Juwel von vielen googeln ( http://elmpowered.skawaii.net/?p = 74 )

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

root hier ist Ihr Wurzelknoten des Baumes. Elem ist das eigentliche Element Objekt, das Sie von Iterieren erhalten.

Das macht Sie benötigen die Wurzel zu wissen, was bedeuten kann, zu verändern, wie Sie für das Parsen von XML einrichten, aber es ist Moll am besten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top