5 votes

XSLT2 : Comment référencer les attributs du nœud courant dans les prédicats XPath2

J'avais posté une autre question avec cet aspect des choses. On m'a dit de clarifier la question, mais cette question était déjà assez longue et compliquée, alors j'en ai créé une nouvelle.

Je veux savoir s'il existe un moyen standard de référencer la actuel l'attribut du nœud dans une expression XPath testant un autre nœud.

À titre d'exemple, considérons le XSLT suivant

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
    <xsl:for-each select="potato/stem[eye]">
        In session <xsl:value-of select="@sessionID"/>, the potato had <xsl:value-of select="/potato/stem[@sessionID=@sessionID][scc]/scc/@leafnumber"/> s.c.c. leaves.
    </xsl:for-each>
</xsl:template>

(Source XML au bas de cette question). (Notez que le for-each fait référence à des nœuds de type stem[eye] mais que la deuxième valeur demandée fait référence à des nœuds de type stem[scc], qui se trouvent sur une branche différente de l'arbre XML source).

Évidemment, la partie "@sessionID=@sessoinID" n'a pratiquement aucun sens, car XPath la perçoit comme "La valeur de l'attribut sessionID du nœud doit être égale à ... la valeur de l'attribut sessionID du nœud".

Mais ce que je veux dire, c'est "Tester pour s'assurer que la valeur de l'attribut seesionID de ce noeud (celui de l'expression XPath) est la même que le sessionID du noeud de n'importe quel noeud /stem[eye] dans lequel je me trouve en ce moment".

Je ne peux pas le faire avec une variable, car vous n'êtes pas autorisé à déclarer une variable dans une clause for-each.

Pour référence, voici la source XML. Sa structure n'est pas celle que l'on souhaiterait, mais c'est ce avec quoi je dois travailler.

<?xml version="1.0" encoding="utf-8"?>
<potato>
<stem sessionID="1">
    <eye number = "25"/>
</stem>
<stem sessionID="3">
    <eye number = "33"/>
</stem>

<stem sessionID="1">
    <scc leafnumber = "234" />
</stem>
<stem sessionID="2">
    <scc leafnumber = "433"/>
</stem>
<stem sessionID="3">
    <scc leafnumber = "463"/>
</stem>

<stem sessionID="1">
    <agd leafnumber = "154"/>
</stem>
<stem sessionID="2">
    <agd leafnumber = "233"/>
</stem>
<stem sessionID="3">
    <agd leafnumber = "113"/>
</stem> 
</potato>

Le résultat que je recherche est :

Lors de la session 1, la pomme de terre avait 234 feuilles s.c.c..

Lors de la session 3, la pomme de terre comptait 463 feuilles s.c.c..

(Bien sûr, tout ceci n'est qu'un exemple de bac à sable. Je réalise qu'il y a probablement des moyens faciles d'accomplir le résultat ci-dessus d'une manière complètement différente, mais j'espère que cet exemple fait passer ma question, qui est de savoir comment utiliser les valeurs associées au nœud actuel (disons, dans un for-each) dans un prédicat pour un XPath qui en recherche un autre).

10voto

Dimitre Novatchev Points 147842

Dans XSLT 1.0, vous pouvez utiliser la fonction standard current() qui fait référence au nœud correspondant au modèle actuel ou au modèle le plus à l'intérieur. xsl:for-each :

/potato/stem[@sessionID=current()/@sessionID][scc]/scc/@leafnumber

ou en définissant une clé (au niveau mondial) :

<xsl:key name="kPotById" match="stem[scc]" use="@sessionID"/>

et en faisant référence à cette clé :

key('kPotById', @sessionID)/scc/@leafnumber

Dans XSLT 2.0 / XPath 2.0, il existe d'autres moyens d'exprimer ce principe. (variables de gamme) :

for $thisSessionID in @sessionId
 return
    /potato/stem[@sessionID=$thisSessionID][scc]/scc/@leafnumber

7voto

Martin Honnen Points 46896

Utilisez par exemple current()/@sessionID pour accéder à la sessionID du nœud actuellement traité (par exemple, celui traité par le for-each dans votre exemple ou par un apply-templates avec traitement en mode push).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X