Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to refer to current node value in XSL for-each test?

Tags:

xml

xslt

xpath

People also ask

What is current () XSLT?

XSLT current() Function The current() function returns a node-set that contains only the current node. Usually the current node and the context node are the same.

What is a current node in XPath How can it be accessed?

The current node is only relevant if you are in an XSLT-scope; it refers to the node the current template is applied to and can be accessed using current() . For plain XPath (without XSLT), this function is not available and the current not neither accessible nor relevant.

What does node () mean in XSLT?

This is called the identity transform. The node()|@* is matching all child nodes ( node() is all text,element,processing instructions,comments) and attributes ( @* ) of the current context.


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 use self::node()[foo] instead. Also, the = operator needs something to match against, in this case the text() 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 just if to accomplish the same task:

<xsl:if test="/books/book[. = 1112]">
    Success
</xsl:if>

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:

  1. Within [ and ] there is no predicate: the "=" operator needs two arguments but only one is provided.

  2. .[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

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>

XSLT has a function specially for this problem.

http://www.w3.org/TR/xslt#function-current


Try with this

<xsl:for-each select="/books/book">
    <xsl:if test="current() = '1112'">
        Success
    </xsl:if> 
</xsl:for-each>