• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • paul wheaton
  • Jeanne Boyarsky
  • Ron McLeod
Sheriffs:
  • Paul Clapham
  • Liutauras Vilda
  • Devaka Cooray
Saloon Keepers:
  • Tim Holloway
  • Roland Mueller
Bartenders:

XSL question: position() strangeness

 
Ranch Hand
Posts: 1056
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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="http://www.w3.org/1999/XSL/Transform"
� � � � � � � � version="1.0">
� <xsl:output 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="*"/>
or
� �<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?
 
Ranch Hand
Posts: 18944
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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()
etc.
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:

Cheers
[ January 11, 2003: Message edited by: Beno�t d'Oncieu ]
 
They worship nothing. They say it's because nothing is worth fighting for. Like this tiny ad:
Smokeless wood heat with a rocket mass heater
https://woodheat.net
reply
    Bookmark Topic Watch Topic
  • New Topic