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?
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)
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
vous pouvez utiliser la notation xpath ...
dans ElementTree.
<parent>
<child id="123">data1</child>
</parent>
xml.findall('.//child[@id="123"]...')
>> [<Element 'parent'>]
, 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>
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+"/..")
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.
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...
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('..')