In Python ElementTree come posso ottenere l'elenco di tutti gli antenati di un elemento in albero?
-
27-09-2019 - |
Domanda
I Need "get_ancestors ricorsiva" la funzione.
>>> dump(tr)
<anc1>
<anc2>
<element> </element>
</anc2>
</anc1>
>>> input_element = tr.getiterator("element")[0]
>>> get_ancestors_recursively(input_element)
['anc1', 'anc2']
Qualcuno può aiutarmi con questo?
Soluzione
Nella versione più recente di ElementTree (v1.3 o successivo), si può semplicemente fare
input_element.find('..')
in modo ricorsivo. Tuttavia, l'ElementTree fornito con Python non ha questa funzionalità, e non vedo nulla nella classe Elemento che guarda verso l'alto.
Credo che questo significa che dovete farlo nel modo più duro:. Tramite una ricerca esaustiva della struttura di elemento
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
Questa è lento a causa della DFS, e tira fuori un sacco di liste per la raccolta dei rifiuti, ma se si può fare con questo dovrebbe andare bene.
Altri suggerimenti
Un'altra opzione è LXML , che fornisce utili estensioni per il costruito nel ElementTree api. Se siete disposti a installare un modulo esterno, ha una bella funzione Element.getparent()
che si potrebbe semplicemente chiamare in modo ricorsivo fino a raggiungere ElementTree.getroot()
. Questo sarà probabilmente la soluzione più veloce e più elegante (come le introduce lxml.etree module
puntatore attributi per gli elementi che punto ai loro genitori, così invece di cercare l'intero albero per le coppie parent/child
propri).
Trovato questa piccola gemma da un sacco di googling ( http://elmpowered.skawaii.net/?p = 74 )
parent = root.findall ( ".// {0} / .." formato. (Elem.tag))
root qui è il nodo principale della struttura. elem è l'oggetto elemento effettivo che si ottiene da iterazione.
Questo non richiede di conoscere la radice, che può significare cambiare come si imposta per l'analisi di XML, ma è minore al meglio.