Subject: Re: Odd bug? in msxml3 xslt implementation
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Tue, 27 Mar 2001 12:34:19 +0100
|
Hi Unico,
Aside from the obvious errors in your XSLT, which Mike pointed out,
the problem is probably because the first time you call the template,
you're setting the $position parameter to a result tree fragment (RTF)
with:
<xsl:with-param name="position">1</xsl:with-param>
The RTF is a little node set that looks like:
+- (root node)
+- (text node) "1"
One of the 'features' of RTFs is that they always evaluate to boolean
true. So when you later do:
item[$position]/name != $name
The $position variable is not a number (it's an RTF), so it's
evaluated as a boolean within the predicate to give:
item[true()]/name != $name
which is equivalent to:
item/name != $name
This tests whether there are *any* name children of the item children
of the current node whose value is not equal to the value of the $name
parameter.
I think that what you wanted was either to set the $position parameter
to a number with the select attribute:
<xsl:with-param name="position" select="1" />
or to explicitly convert the $position parameter to a number within
the predicate with:
item[number($position)]/name != $name
> ... I wouldn't be able to use the above xslt since it only checks for
> equality to the previous item name, unless I found a way to sort the items
> by item name in wich case I cannot use a the named template strategy I
> guess. Does anybody have a solution to this problem, is there perhaps an
> xpath statement that would allow me to filter down my node set of <item>s to
> only those that have unique item names, in wich case I could use iteration ?
Yes. For each item element, you can check whether there are *any*
preceding item element names that are the same as this one:
preceding-sibling::item/name = name
(Note again that if one of the operands for a comparison operator
is a node set then the comparison is true if it's true for *any* of
the nodes in that node set.)
So you can pick all the item elements who *don't* have a preceding
item with the same name with:
item[not(preceding-sibling::item/name = name)]
Those are the unique items, and as you say you can iterate over them,
or apply templates to them.
If you have a lot of item elements, you might want to use the
Muenchian method (which uses keys) instead. See
http://www.jenitennison.com/xslt/grouping for more information.
I hope that helps,
Jeni
---
Jeni Tennison
http://www.jenitennison.com/
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
|