[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: preceding-sibling context

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

>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 -->
  </xsl:for-each>

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>
  </xsl:variable>

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

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
variable).

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>

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

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
problem.

Cheers,

Jeni

Jeni Tennison
http://www.jenitennison.com/




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


Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.