nœud d'accès à L'Élémenttree nœud parent

j'utilise le module Python ElementTree. Il est facile d'avoir accès aux enfants, mais qu'en est-il des noeuds de parents ou de frères et sœurs? - cela peut-il être fait efficacement sans traverser l'arbre entier?

43
demandé sur hoju 2010-01-31 08:02:47

8 réponses

il n'y a pas de support direct sous la forme d'un attribut parent , mais vous pouvez peut-être utiliser les modèles décrits ici pour obtenir l'effet désiré. L'une des gaines suivantes est suggérée (à partir du lien-to-post) pour créer une cartographie enfant-parent pour un arbre entier:

parent_map = dict((c, p) for p in tree.getiterator() for c in p)
34
répondu Vinay Sajip 2010-01-31 08:04:25

Vinay réponse doivent encore travailler, mais pour Python 2.7+ 3,2+ la suivante est recommandée:

parent_map = {c:p for p in tree.iter() for c in p}

getiterator() est déprécié en faveur de iter() , et il est agréable d'utiliser le nouveau dict liste de compréhension constructeur.

Deuxièmement, lors de la construction d'un document XML, il est possible qu'un enfant ait plusieurs parents, bien que cela soit supprimé une fois que vous sérialisez le document. Si cela compte, vous pourriez essayer ceci:

parent_map = {}
for p in tree.iter():
    for c in p:
        if c in parent_map:
            parent_map[c].append(p)
            # Or raise, if you don't want to allow this.
        else:
            parent_map[c] = [p]
            # Or parent_map[c] = p if you don't want to allow this
15
répondu supergra 2017-05-23 11:54:56

vous pouvez utiliser la notation xpath ... dans ElementTree.

<parent>
     <child id="123">data1</child>
</parent>

xml.findall('.//child[@id="123"]...')
>> [<Element 'parent'>]
4
répondu josven 2015-10-22 12:18:20

, Comme mentionné dans Obtenir de l'élément parent après aide de la méthode find (xml.programme etree.ElementTree) vous devez effectuer une recherche indirecte pour parent. Ayant xml:

<a>
 <b>
  <c>data</c>
  <d>data</d>    
 </b>
</a>

en supposant que vous avez créé l'élément etree dans la variable xml , vous pouvez utiliser:

 In[1] parent = xml.find('.//c/..')
 In[2] child = parent.find('./c')

résultant en:

Out[1]: <Element 'b' at 0x00XXXXXX> 
Out[2]: <Element 'c' at 0x00XXXXXX>

Parent supérieur serait trouvé comme: secondparent=xml.find('.//c/../..') être <Element 'a' at 0x00XXXXXX>

3
répondu Vaasha 2017-05-23 12:26:20

une autre façon si vous voulez simplement un parent d'un sous-élément et aussi connu le xpath du sous-élément.

parentElement = subElement.find(xpath+"/..")
2
répondu MK at Soho 2014-02-23 02:41:36

si vous utilisez lxml, j'ai pu obtenir l'élément parent avec ce qui suit:

parent_node = next(child_node.iterancestors())

cela va soulever une exception StopIteration si l'élément n'a pas d'ancêtres - alors soyez prêt à attraper que si vous pouvez courir dans ce scénario.

2
répondu Shadow 2018-03-08 04:13:38

The XPath".."le sélecteur ne peut pas être utilisé pour récupérer le noeud parent sur 3.5.3 ou 3.6.1 (au moins sur OSX), eg en mode interactif:

import xml.etree.ElementTree as ET
root = ET.fromstring('<parent><child></child></parent>')
child = root.find('child')
parent = child.find('..') # retrieve the parent
parent is None # unexpected answer True

la dernière réponse brise tous les espoirs...

0
répondu jlaurens 2018-07-04 07:56:12

regardez le 19.7.2.2. section: pris en charge la syntaxe XPath ...

trouver le parent du noeud en utilisant le chemin:

parent_node = node.find('..')
-1
répondu Alf 2017-12-13 23:29:22