Let's say I have an XML doc like this:
<books>
<book>1110</book>
<book>1111</book>
<book>1112</book>
<book>1113</book>
</books>
I'm trying to setup a condition that tests the value of the current node in the for-each
, but I'm doing something wrong:
<xsl:for-each select="/books/book">
<xsl:if test=".[='1112']">
Success
</xsl:if>
</xsl:for-each>
What am I doing incorrectly?
-
Using
.
can, indeed, refer to the current (or "context") node, but not the way you're using it here. In XPath,.[foo]
is not valid syntax — you need to useself::node()[foo]
instead. Also, the=
operator needs something to match against, in this case thetext()
selector to access the element's text contents:<xsl:for-each select="/books/book"> <xsl:if test="self::node()[text()='1112']"> Success </xsl:if> </xsl:for-each>
As stated in the other answers, however, unless your
for-each
is performing other operations as well, you don't need to iterate at all and can use justif
to accomplish the same task:<xsl:if test="/books/book[. = 1112]"> Success </xsl:if>
Dimitre Novatchev : .[someBoolean] is syntactically invalid in XPath 1.0.Ben Blank : Thanks; when testing, I'd actually actually tested the non-looping version and so never encountered the `.[…]` problem. *blush*Dimitre Novatchev : But plese, do correct your answer -- it is still the accepted one. If you mention that .[something] is incorrect syntax, then I'll cancel my downvote.Ben Blank : Re-clarified my clarifications. :-) -
While Ben has answered your question correctly, using for-each is most definitely the wrong general approach. After all this is XSLT. So you are probably more looking for something like this:
<xsl:if test="/books/book[text()='1112']"> Success </xsl:if>
Ben Blank : True; I assumed the OP was just snipping out the relevant portion of a larger `for-each` block, but if that's the entirety of it, it would be far better to use this simple `if` instead. -
I'm trying to setup a condition that tests the value of the current node in the for-each, but I'm doing something wrong:
The first thing that is incorrect is the syntax:
.[='1112']
There are two things wrong here:
Within [ and ] there is no predicate: the "=" operator needs two arguments but only one is provided.
.[x = y]
is still invalid syntax, although the predicate is OK. This has to be specified as:self::node()[condition]
The second thing in the provided code that can be improved is the
<xsl:for-each>
instruction, which isn't necessary at all; A single XPath expression will be sufficient.To summarize, one possible XPath expression that evaluates to the required boolean value is:
/books/book[. = '1112']
If it is really necessary that the condition be tested inside the
<xsl:for-each>
instruction, then one correct XPath expression I would use is:. = '1112'
The above is a string comparison and may not evaluate to
true()
if there are spaces around. Therefore, a numerical comparison may be better:. = 1112
-
XSLT has a function specially for this problem.
0 comments:
Post a Comment