[xsl] position() in xsl:for-each

Subject: [xsl] position() in xsl:for-each
From: Vidar Ramdal <vramdal@xxxxxxxxx>
Date: Fri, 9 Jul 2004 10:32:02 +0200
I have a very simple XML tree like this:

  <object name="name1" type="type1">data1</object>
  <object name="name2" type="type1">data2</object>
  <object name="name3" type="type1">data3</object>
  <object name="name4" type="type1">data4</object>
  <object name="name5" type="type2">data5</object>

Now, I want to exclude the "type2" object, and transform this to a
HTML table, displaying 2 <object>s per row:


So I've written this template:

<xsl:template match="objects">
     <xsl:for-each select="object[@type='type1'][position() mod 2 = 1]">
        <td><xsl:apply-templates select="."/></td>
        <td><xsl:apply-templates select="following-sibling::*[1]"/></td>

This gives the desired result, but today I started wondering *why* it worked :) 

What puzzles me is that following-sibling::*[1] selects the next
element in the input tree, and not in the nodeset I select in the

That is, why does following-sibling::*[1] give me <object
name="name2"> and not <object name="name3"> ?

It seems to me that it works as if I had not specified [position() mod
2 = 1], but honoring [@type='type1'] (as it does not output the
<object type="type2">)

I've browsed the XSLT spec, but couldn't find anything that explains
this behaviour. Anyone?

Vidar S. Ramdal

Current Thread