Re: preceding-sibling context

Subject: Re: preceding-sibling context
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Thu, 2 Nov 2000 17:23:18 -0400 (EST)

>does the preceding-sibling axis look at the document or the current context
>node-set?  In my trials it seems to look at all the siblings in the document
>rather than just the context node set.

It always looks at the siblings in the source tree (i.e. usually the source
document).  *All* the XPath axes deal with the position of the node within
the source tree: none of them care about the context node set.

>If it is not designed to look at the node-set, then is it possible to see
>the previous node of the current context node-set some other way?

It depends on how the context node set is generated.  For example, if you
had something like:

  <xsl:variable name="pigs" select="//pig" />
  <xsl:for-each select="$pigs">
    <!-- I want to know who the previous pig is here -->

then because the context node list is stored within a variable, and you
know the position of the current node within that node list (through
position()), you can do:

  <xsl:variable name="pos" select="position()" />
  <xsl:variable name="previous" select="$pigs[position() = $pos - 1]" />

Another possibility, if you're prepared to use the 'node-set' extension
function, is to create a source tree in which the nodes in the node set
you're interested in *are* siblings, and use that instead.  For example:

  <xsl:variable name="pigs">
    <xsl:for-each select="//pig">
      <xsl:copy-of select="pig" />

  <xsl:for-each select="saxon:node-set($pigs)">
    <xsl:variable name="previous" select="preceding-sibling::pig" />

This is a bit of a cleaner method if you're applying templates rather than
using xsl:for-each.  If you use the first method and apply templates, the
template matching 'pig' would have to know what the variable $pigs
contains, which means that it would either have to be a global variable or
be passed into the template as a parameter.  With the second method,
preceding-sibling:: could be applied wherever you need it, but on the other
hand the original source document is inaccessible (apart from through a

A final method is to use what you know about what's in the context node set
to use a different XPath to find the previous member of the context node
set.  For example:

  <xsl:for-each select="//pig">
    <xsl:variable name="previous" select="preceding::pig" />

  <xsl:for-each select="//litter/pig[@runt = 'no']">
    <xsl:variable name="previous"
                  select="preceding::pig[parent::litter and @runt = 'no']" />

Of course the difficulty with this is maintaining the similarity between
the node set selection and the method of identifying the previous node
within that set.

Anyway, I hope this has given you a few ideas about how to tackle your



Jeni Tennison

 XSL-List info and archive:

Current Thread