RE: [xsl] preceding-sibling inside for-each appears to fail

Subject: RE: [xsl] preceding-sibling inside for-each appears to fail
From: "Michael Kay" <michael.h.kay@xxxxxxxxxxxx>
Date: Mon, 10 Feb 2003 10:32:33 -0000
> What I'm having a little difficulty understanding is exactly why 
> preceding-sibling, in this example, requires a positional predicate 
> while following-sibling doesn't. Also, I thought that the node-set 
> returned by the select attribute in the for-each element was 
> complete.

When you do
<xsl:value-of select="xxxxx-sibling::*"/>
<xsl:value-of select="xxxxx-sibling::*[1]"/>

there are several effects interacting.

Firstly, the XPath expression xxxx-sibling::node() selects a set of
nodes. The XSLT <xsl:value-of> instruction ignores all the nodes in the
set except the one that is first in document order. So <xsl:value-of
select="following-sibling::*"/> gives you the immediately following
sibling, while <xsl:value-of select="preceding-sibling::*"/> gives you
the _first_ (most distant) preceding sibling.

Secondly, a filter used within a step is applied to nodes in terms of
their distance from the context node. The filter [1] selects the node
that is closest to the context node. So following-sibling::*[1] selects
the immediately following sibling, while preceding-sibling::*[1] selects
the immediately preceding (least distant) sibling.

(Note the "within a step". If your write (preceding-sibling::*)[1], then
the [1] is no longer within a step. A filter that is outside a step
considers nodes in document order, so this expression will select the
first (most distant) preceding sibling.)

This explains why adding the filter "[1]" to the instruction
<xsl:value-of select="following-sibling::*"/> makes no difference to the
outcome, while adding it in the preceding-sibling case makes a big

Michael Kay
Software AG
home: Michael.H.Kay@xxxxxxxxxxxx
work: Michael.Kay@xxxxxxxxxxxxxx 

 XSL-List info and archive:

Current Thread