Obtenez tous les ancêtres du nœud courant
Je veux obtenir tous les ancêtres du nœud actuel:
XML:
<root>
<item title="a">
<item title="b">
<item title="c"></item> <!--CURRENT-->
<item title="d"></item>
</item>
<item title="x">
<item title="y"></item>
<item title="z"></item>
</item>
</item>
</root>
Résultat:
<item title="a">...</item>
<item title="b">...</item>
Edit:
Réponses avec axes ancêtre sont beaux.
Mon problème était ailleurs, dans XSLT
XSLT:
<xsl:variable name="curr" select="//item[@title = 'c']"></xsl:variable>
<xsl:variable name="test" select="$curr/ancestor::item"></xsl:variable>
<xsl:for-each select="$test/item">
<xsl:value-of select="@title"></xsl:value-of>
</xsl:for-each>
Retourne:
bcdx
Edit2: pour dimitre et pour tous ceux qui ont un problème similaire
Toutes les réponses à ma question étaient bonnes.
Juste XSLT () me renvoie un résultat étrange et @Mads Hansen m'a corrigé.
DE TRAVAIL FINAL EXEMPLE:
XML:
<?xml version="1.0" encoding="utf-8"?>
<root>
<item title="a">
<item title="b">
<item title="c"></item>
<item title="d"></item>
</item>
<item title="x">
<item title="y"></item>
<item title="z"></item>
</item>
</item>
</root>
XSLT:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:variable name="curr" select="//item[@title = 'c']"></xsl:variable>
<xsl:variable name="test" select="$curr/ancestor::item"></xsl:variable>
<xsl:for-each select="$test">
<xsl:value-of select="@title"></xsl:value-of>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Retourne:
ab
Alors, quel est le problème avec le code XSLT? Je vois l'un des principaux problèmes, il n'est pas syntaxiquement valide -- il n'y a même pas un seul modèle dans le présent code. Pour cette raison, aucune des réponses significatives peuvent être donnés. S'il vous plaît, de modifier la question et de fournir un ensemble (mais aussi petit que possible) la transformation qui peut être exécuté par tout le monde, de sorte que le problème peut être reproduit. Aussi, s'il vous plaît, fournir à l'exact résultat attendu et pourquoi le résultat que vous recevez est un problème.
OriginalL'auteur Moriarty | 2012-09-11
Vous devez vous connecter pour publier un commentaire.
Congradulations Adam pour un très rapide de la première réponse.
Juste pour ajouter un petit détail:
Figurant dans votre liste résultat attendu ne correspond pas à vos paroles. l'élément racine aussi un ancêtre du nœud et le document est aussi un ancêtre du nœud.
... sera de retour d'une séquence dans cet ordre:
item[@title='b']
item[@title='a']
root
élément (un.k.un. l'élément de document)/
À obtenir le résultat que vous avez énumérés, vous avez besoin de:
L'effet de l' /. est de modifier l'ordre de retour à l'avant de l'ordre du document. L'ordre d'origine de l'ancêtre:: est l'inverse de l'ordre du document.
Mise à jour: Illustration des points abordés dans le commentaire d'alimentation.
Cette feuille de style (avec des OP d'entrée)...
... seront de sortie 'ba' illustrer le point que ancestor:: est en effet une inversion de l'axe. Et pourtant, cette feuille de style ...
... a le résultat inverse "ab". C'est instructif car il montre que, dans XSLT 1.0 (pas de XSLT 2.0), les supports de supprimer l'inverse de la nature, et il devient un document commandé node-set.
L'OP a demandé un transformer quelque chose comme....
Celle-ci rentre " ab " (XSLT 2.0, il serait de retour 'ba'). Pourquoi? Parce que dans XSLT 1.0, le xsl:for-each instruction ignore l'inverse " de l'axe et des processus dans l'ordre du document (à moins qu'un xsl:sort d'instruction dit le contraire).
/.
peu.j'ai le même résultat avec /. et sans. <xsl:for-each select="//[@titre = 'c']/ancestor::item"> est la même <xsl:for-each select="//[@titre = 'c']/ancestor::point/."> .. résultat: ab
Dans XPATH 1.0 ou 2.0, ancestor:: est en effet une inversion de l'axe (voir w3.org/TR/xpath la section 2.4; et w3.org/TR/xpath20 la section 3.2.1.1), Mais comment vous comptez l'utiliser XSLT peut modifier l'ordre et le comportement dépend de la version de XSLT. ....
En XSLT 1.0, un xsl:for-each instruction ignorer l'ordre dans l'expression xpath, (à moins qu'un tri s'applique). Mais dans XSLT 2.0, le instrinsic ordre est conservé.
Pour comprendre ce que je veux dire, essayez d'utiliser une position de prédicat. Même en XSLT 1.0 à l'aide de xsl:for-each, vous obtenez l'ordre inverse.
OriginalL'auteur Sean B. Durkin
Désignés nœuds ne sont évidemment pas des tous ancêtres de la "verte" nœud.
Pour sélectionner tous ancêtres utilisation:
Cela sélectionne tous les ancêtre des nœuds de la première conext nœud (ou nœud), y compris l'élément supérieur et son parent -- le nœud racine
/
-- qui est un nœud, mais ce n'est pas un élément.Pour sélectionner tous les élément ancêtres utilisation:
Ceci est similaire à l'expression précédente, mais ne sélectionnez pas la nœud racine (
/
), car il n'est pas un élément.Pour sélectionner tous les ancêtres nommé
item
, utilisez:Ne Remarque: Toutes les expressions ci-dessus supposent que
(//item[@title='c'])[1]
est le contexte initial nœud (nœud actuel). Si cette hypothèse n'est pas correcte, alors(//item[@title='c'])[1]/
doit être ajouté à chacune des expressions.Note2: je recommande fortement pour l'apprentissage de XPath pour utiliser un outil comme le XPath Visualizer. Pendant de nombreuses années, cet outil a aidé des milliers de personnes d'apprendre XPath de façon amusante -- en jouant avec des expressions XPath et en observant le résultat de leur évaluation.
Note: XPath Visualizer a été créé par moi en l'an 2000 et n'a jamais été un produit financier. Je le recommande uniquement fondée sur sa valeur pour les utilisateurs, éprouvée au cours de nombreuses années
OriginalL'auteur Dimitre Novatchev
Vous pouvez utiliser xpath
ancestor::item
OriginalL'auteur Adam Hopkinson
La raison pour laquelle vous avez été la sortie
bcdx
au lieu deab
est parce que votre<xsl:for-each>
est une itération sur l'ensemble de laitem
les enfants de la sélectionitem
éléments, plutôt que de simplement une itération sur les éléments sélectionnés dans le$test
variable.Changer votre pour-chacun de simplement effectuer une itération sur
$test
:OriginalL'auteur Mads Hansen