This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
RE: limiting preceding axis by ancestor
- From: "Michael Kay" <michael dot h dot kay at ntlworld dot com>
- To: <xsl-list at lists dot mulberrytech dot com>
- Date: Tue, 7 May 2002 23:23:37 +0100
- Subject: RE: [xsl] limiting preceding axis by ancestor
- Reply-to: xsl-list at lists dot mulberrytech dot com
> I have a document where there are many instances of <foo>.
> Each <foo> may
> have many <bar> children. <bar> is itself recursive to
> several levels.
>
> <foo>
> <bar>
> <bar>
> <foo>
> <bar>
> <bar>
> <bar>
>
> I want to test to see if any preceding <bar> has the same value as the
> current <bar> but limit the test to those <bar> elements are
> children of the
> immediate <foo> ancestor.
By "preceding" do you mean preceding in the sense of the preceding axis,
which excludes ancestors of the context node? I'll assume you do.
Using XPath 2.0 you could write
preceding::bar intersect ancestor::foo//*
or
preceding::bar except ancestor::foo/preceding::bar
If you do want to include ancestors of the context node, you could write
ancestor::foo/descendant::bar[.<<current()]
which is probably going to be the most efficient as it's the only one that
doesn't look outside the foo subtree.
Several XSLT 1.0 processors have xx:intersect() and xx:difference()
extension functions which you could use to simulate the first two of these.
I can't immediately think of an XPath 1.0 solution that only looks in the
foo subtree. But there's an XSLT solution using xsl:number -
<xsl:variable name="thispos">
<xsl:number level="any" from="foo"/>
</xsl:variable>
<xsl:for-each select="ancestor::foo//bar">
<xsl:variable name="thatpos">
<xsl:number level="any" from="foo"/>
</xsl:variable>
<if test="$thatpos < $thispos">
-- process this node --
</xsl:if>
</xsl:for-each>
Michael Kay
Software AG
home: Michael.H.Kay@ntlworld.com
work: Michael.Kay@softwareag.com
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list