xsl-list
[Top] [All Lists]

RE: preceding-sibling inside for-each appears to fail

2003-02-10 03:32:33
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::*"/>
or
<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
difference.

Michael Kay
Software AG
home: Michael(_dot_)H(_dot_)Kay(_at_)ntlworld(_dot_)com
work: Michael(_dot_)Kay(_at_)softwareag(_dot_)com 


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list