Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XSL - How to tell if element is last in series

Tags:

xml

xslt

I have an XSL template that is selected for execution (below). What I would like to do is be able to tell if I am the last Unit being matched.

  <xsl:template match="Unit[@DeviceType = 'Node']">
    <!-- Am I the last Unit in this section of xml? -->
    <div class="unitchild">
      Node: #<xsl:value-of select="@id"/>
    </div>
  </xsl:template>

Example XML

<Unit DeviceType="QueueMonitor" Master="1" Status="alive" id="7">
    <arbitarytags />
    <Unit DeviceType="Node" Master="0" Status="alive" id="8"/>
    <Unit DeviceType="Node" Master="0" Status="alive" id="88"/>
</Unit>
like image 936
Chris Avatar asked May 12 '10 09:05

Chris


People also ask

How do I get the last element of XPath?

Using XPath- last() method, we can write the Java code along with the dynamic XPath location as: findElement(By. xpath("(//input[@type='text'])[last()]"))

What is Number () in XSLT?

If the argument is a boolean value, the value true is converted to the number 1 ; the value false is converted to the number 0 . If the argument is a node-set, the node-set is converted to a string as if it were passed to the string() function, then that string is converted to a number like any other string.

What is text () in XSLT?

The <xsl:text> element is used to write literal text to the output. Tip: This element may contain literal text, entity references, and #PCDATA.

Does XSLT use XPath?

XPath is a major element in the XSLT standard. XPath can be used to navigate through elements and attributes in an XML document.


2 Answers

The currently selected answer is generally incorrect!

<xsl:if test="not(following-sibling::Unit)">

This Will not work with any XML document and any <xsl:apply-templates>

The original question is about the last Unit being matched, not the last sibling! Which is the last Unit being matched depends only on the expression in the select attribute of <xsl:apply-templates>, not on the physical properties of the XML document.

The way to do it:

<xsl:apply-templates select="SomeExpression"/>

then in the template that matches nodes selected by SomeExpression:

<xsl:if test="position() = last()">
. . . . 
</xsl:if>

This checks if the current node is the last in the node-list selected by <xsl:apply-templates>, not that the current node is the last sibling. This answers exactly the original question.

If the question was framed in a different way, asking how to recognize if the last sibling Unit is the current node, then the best solution would be to specify a separate template for this last sibling node:

<xsl:template match="Unit[last()]">
    . . . . 
</xsl:template>

Do note, that in this case there is no need to write any conditional logic inside a template to test if the current node is "the last".

like image 123
Dimitre Novatchev Avatar answered Sep 30 '22 17:09

Dimitre Novatchev


If you want to test whether it is the last Unit element at the same level (with the same parent element), even if there are arbitrary tags before, after, and in-between then this would work:

<xsl:if test="not(following-sibling::Unit)">

However, if you are applying templates for a subset, the last in the document may not be in the set being processed. For that, you can test if the position() = last()

<xsl:if test="position() = last()">
like image 42
Mads Hansen Avatar answered Sep 30 '22 17:09

Mads Hansen