In Python ElementTree come posso ottenere l'elenco di tutti gli antenati di un elemento in albero?

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

  •  27-09-2019
  •  | 
  •  

Domanda

I Need "get_ancestors ricorsiva" la funzione. Una corsa campione può essere

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

È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top