This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: preceding-sibling context
- To: <xsl-list at mulberrytech dot com>
- Subject: Re: preceding-sibling context
- From: ken dot dickerson at philips dot com
- Date: Fri, 3 Nov 2000 15:54:50 -0400 (EST)
- Reply-To: xsl-list at mulberrytech dot com
What name space are you using to use xsl:variable? I have specified "http://www.w3.org/TR/WD-xsl" and I get a load error "Keyword xsl:variable may not be used in namespace http://www.w3.org/TR/WD-xsl."
Thanks,
-Ken
mail@jenitennison.com@SMTP@mulberrytech.com on 11/02/2000 06:24:07 PM
Please respond to xsl-list@mulberrytech.com@SMTP
Sent by: owner-xsl-list@mulberrytech.com
To: prospect@flex.com.au@SMTP
cc: xsl-list@mulberrytech.com@SMTP
Subject: Re: preceding-sibling context
Classification:
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
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list