Hey,
I know there is the current()
function to retrieve the current node in XSL, but is there a way to be able to reference the "previous" and "next" nodes in reference to the current position?
Hey,
I know there is the current()
function to retrieve the current node in XSL, but is there a way to be able to reference the "previous" and "next" nodes in reference to the current position?
Assuming you are talking about next and previous nodes in the document structure, as opposed to the current execution flow (such as a for-each
loop), see the preceding-sibling
and following-sibling
axes: XPath Axes on W3.
To get the next node of the same name:
following-sibling::*[name() = name(current())]
Depending on the context, you may need to use name(.)
in the first part.
No. The current context cannot know which nodes are "next" or "previous".
This is because when, for example, templates are applied, the mechanics go like this:
<xsl:apply-templates select="*" /><!-- select 3 nodes (a,b,c) -->
current()
node is defined, and position()
is defined, but other than that the template has no knowledge of the execution flow.You can do use the following::sibling
or preceding::sibling
XPath axes, but that's something different from knowing what node will be processed next
EDIT
The above explanation tries to answer the question as it has been asked, but the OP meant something different. It's about grouping/outputting unique nodes only.
As per the OP's request, here a quick demonstration of how to achieve a grouping using the XPath axes.
XML (the items are pre-sorted):
<items>
<item type="a"></item>
<item type="a"></item>
<item type="a"></item>
<item type="a"></item>
<item type="b"></item>
<item type="e"></item>
</items>
XSLT
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:template match="/items">
<!-- copy the root element -->
<xsl:copy>
<!-- select those items that differ from any of their predecessors -->
<xsl:apply-templates select="
item[
not(@type = preceding-sibling::item/@type)
]
" />
</xsl:copy>
</xsl:template>
<xsl:template match="item">
<!-- copy the item to the output -->
<xsl:copy-of select="." />
</xsl:template>
</xsl:stylesheet>
Output:
<items>
<item type="a"></item>
<item type="b"></item>
<item type="e"></item>
</items>
Hi,
You could track previous and current in variables for later handling. I.e. you can keep tag(i-2), tag(i-1) and work with them in tag(i).
Just another idea.
Regards.