This week's giveaway is in the Android forum.
We're giving away four copies of Android Security Essentials Live Lessons and have Godfrey Nolan on-line!
See this thread for details.
The moose likes XML and Related Technologies and the fly likes XSL question: position() strangeness Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login

Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Engineering » XML and Related Technologies
Bookmark "XSL question: position() strangeness" Watch "XSL question: position() strangeness" New topic

XSL question: position() strangeness

Ron Newman
Ranch Hand

Joined: Jun 06, 2002
Posts: 1056
Given the following XML input:
� <test>
� <scan>1</scan>
� <scan>2</scan>
� <scan>3</scan>
� <scan>4</scan>
� <scan>5</scan>
� </test>
and the following XSL stylesheet:
� <xsl:stylesheet xmlns:xsl=""
� � � � � � � � version="1.0">
� <xslutput method="text"/>
� <xsl:template match="text()"/>
� <xsl:template match="test">
� � �<xsl:apply-templates/>
� </xsl:template>
� <xsl:template match="scan">
� � �content:<xsl:value-of select="."/>, position:<xsl:value-of select="position()"/>
� � �<xsl:if test="position() = last()"> I'M LAST!</xsl:if>
� </xsl:template>
� </xsl:stylesheet>
Why do I get this output?
� �content:1, position:2
� �content:2, position:4
� �content:3, position:6
� �content:4, position:8
� �content:5, position:10
It's acting as if there were other children of <test>, which there aren't.� It also doesn't seem to think the last child is really last.� This happens with both Xalan and Saxon.
If I change
� �<xsl:apply-templates/>
to either
� �<xsl:apply-templates select="*"/>
� �<xsl:apply-templates select="scan"/>
I get
� �content:1, position:1
� �content:2, position:2
� �content:3, position:3
� �content:4, position:4
� �content:5, position:5 I'M LAST!
which looks a lot more reasonable to me.
What's going on here?

Ron Newman - SCJP 1.2 (100%, 7 August 2002)
Ranch Hand

Joined: Nov 22, 2008
Posts: 18944
Hi Ron,
In a match template, the context is the whole input document, so the context position is equal to the numbered position of the node across all nodes (element, attribute, text node, comment, processing instruction)
The list of nodes is as follows:
1. test
2. scan
3. text()
4. scan
5. text()
If the template is applied without a select, you may use the preceding-sibling and following-sibling axis to achieve this result. The following template, for instance, would give the expected results:

An other way (cleaner) to do this is to use a for-each construct:

[ January 11, 2003: Message edited by: Beno�t d'Oncieu ]
subject: XSL question: position() strangeness
Similar Threads
Data Structure for logic tree
XSLT/XPath - Find unique text node value
inserting data from XML to database
accessing Attribute values of element.
Generating xsl to convert Xml into text format using transformation engine.