Re: [xsl] Inconsistent solution from a conditional data-set by group methods

Subject: Re: [xsl] Inconsistent solution from a conditional data-set by group methods
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Fri, 20 Apr 2001 08:11:35 +0100
Hi Yang,

> Using Muenchian procedures , I define key function as following phrase,
> <xsl:key name="Listings" match="line" use="name" />

Here, you're indexing *all* the line elements by their name.  So when
you access the key with some particular name, then you get all the
line elements with that name, including those for which it's not true
that substring(salesno, 10, 2) = '03'.

> and then supposedly obtain a set of unique set of name listing from:
> <xsl:for-each
> select="//line[substring(salesno,10,2)='03'][generate-id(.)=generate-id(key(
> 'Listings',name)[1])]">
>   <xsl:value-of select="name"/>
> </xsl:for-each>

Now here, you're going through *only* those line elements where
substring(salesno, 10, 2) = '03' is true.  You're testing whether each
of those line elements is the same as the first line element that you
get when you retrieve the lines with that name using the key.  So,
take a look at the lines named AAA in your source:


You're only looking at that third line.  When you call the key(), then
the *first* line is returned, because it's the first line in the
document with the name 'AAA'.  Since that line isn't the same as the
third line, then you don't get the third line coming out of the

> So I change key function by adding predicates
> [substring(salesno,10,2)='03'] , such as

Yes - that will only index the lines that you're actually interested
in (which is a good idea anyway - it's good to keep key hashtables
small so that they don't take up too much memory).

> <xsl:key name="Listing2" match="line[substring(salesno,10,2)='03']"
> then use it with for-each element and then get a good solution this
> time.

That's right, because the third line in the above will be the *first*
one returned by the key - it won't see the first two because they
don't match the key's match pattern.

BTW, if you have unique salesno elements for all your lines, then
rather than generating IDs for each line (which can take time), then
you could use the salesno elements as the basis of the comparison.  So
change the xsl:for-each select to:

             [salesno = key('Listing2',name)[1]/salesno]

I hope that clarifies things a bit.  Do ask further questions if
there's something that's still unclear.



Jeni Tennison

 XSL-List info and archive:

Current Thread