Re: [xsl] Exclude by Sibling Condition

Subject: Re: [xsl] Exclude by Sibling Condition
From: Ragulf Pickaxe <ragulf.pickaxe@xxxxxxxxx>
Date: Fri, 2 Dec 2005 09:57:33 +0100
Hi Mike,

> What I ended up doing is the following:
>
> <xsl:for-each select="page">
>    <xsl:variable name="prev"
select="preceding-sibling::page[position()=1]"/>
>    <xsl:if test="not($prev) or @tab!=$prev/@tab">
>
> I'm not sure how this differs from your method but I found that a)
> [position()=1] must be used to isolate only the immediate sibling and b)
> the @tab!=$prev/@tab strangely returns false if $prev is nil.

Why would you want to check only the immediate preceding sibling on
whether it is the same?
Yes, this works using your sample XML, but would not work with:

 <page name="p0" tab="products"/>
 <page name="d" tab="downloads"/>
 <page name="p1" tab="products"/>
 <page name="s" tab="support"/>
 <page name="p2" tab="products"/>

Of course, if you are sure that the order is as stated in your XML,
then yours would always work.

The other thing is that it is a matter of style: Jay Bryant's solution
will choose _only_ those elements that you want, in his case, the last
page element that has a given value of the tab attribute.

Your solution gets _all_ page elements, _then_ filters out (by your
if-statement) those elements that are not wanted (with the twist about
using position() that I have mentioned above). Insidently,
[position()=1] can be written as simply [1] which expands to the same.

On your other question, which is a problem in your solution only, look
to, for example Michael Kay's XSLT Programmer's Reference (2nd
edition), page 88:
"... when you compare an empty node-set to a string or number the
result is always false, regardless of which comparison operator you
use."

Therefore, "not(a=b)" is, in general, not equivalent with "a!=b".

Regards,
Rafulf Pickaxe :-)

Current Thread