Disons que j'ai un document XML comme celui-ci:
<books>
<book>1110</book>
<book>1111</book>
<book>1112</book>
<book>1113</book>
</books>
J'essaie de configurer une condition qui teste la valeur du nœud actuel dans le for-each
, mais je fais quelque chose de mal:
<xsl:for-each select="/books/book">
<xsl:if test=".[='1112']">
Success
</xsl:if>
</xsl:for-each>
Qu'est-ce que je fais mal?
L'utilisation de .
Peut en effet faire référence au nœud actuel (ou "context"), mais pas à la façon dont vous l'utilisez ici. Dans XPath, .[foo]
N'est pas une syntaxe valide - vous devez utiliser self::node()[foo]
à la place. De plus, l'opérateur =
A besoin de quelque chose pour correspondre, dans ce cas, le sélecteur text()
pour accéder au contenu texte de l'élément:
<xsl:for-each select="/books/book">
<xsl:if test="self::node()[text()='1112']">
Success
</xsl:if>
</xsl:for-each>
Comme indiqué dans les autres réponses, cependant, à moins que votre for-each
N'effectue également d'autres opérations, vous n'avez pas besoin de répéter du tout et vous pouvez utiliser simplement if
pour accomplir la même tâche:
<xsl:if test="/books/book[. = 1112]">
Success
</xsl:if>
J'essaie de configurer une condition qui teste la valeur du nœud actuel dans le for-each, mais je fais quelque chose de mal:
La première chose qui est incorrecte est la syntaxe:
.[='1112']
Il y a deux choses qui ne vont pas ici:
Dans [et] il n'y a pas de prédicat: l'opérateur "=" a besoin de deux arguments mais un seul est fourni.
.[x = y]
Est toujours une syntaxe non valide, bien que le prédicat soit OK. Cela doit être spécifié comme:
self :: node () [condition]
La deuxième chose dans le code fourni qui peut être amélioré est l'instruction <xsl:for-each>
, Qui n'est pas du tout nécessaire; Une seule expression XPath sera suffisante.
Pour résumer, une expression XPath possible qui évalue à la valeur booléenne requise est:
/books/book[. = '1112']
S'il est vraiment nécessaire que la condition soit testée dans l'instruction <xsl:for-each>
, alors une expression XPath correcte que j'utiliserais est:
. = '1112'
Ce qui précède est une comparaison de chaînes et peut ne pas correspondre à true()
s'il y a des espaces autour. Par conséquent, ne comparaison numérique peut être meilleure:
. = 1112
Bien que Ben ait répondu correctement à votre question, l'utilisation de for-each est certainement la mauvaise approche générale. Après tout, c'est XSLT. Donc, vous recherchez probablement plus quelque chose comme ça:
<xsl:if test="/books/book[text()='1112']">
Success
</xsl:if>
XSLT a une fonction spécialement pour ce problème.
Essayez avec ça
<xsl:for-each select="/books/book">
<xsl:if test="current() = '1112'">
Success
</xsl:if>
</xsl:for-each>