RE: [xsl] grouping by unique...

Subject: RE: [xsl] grouping by unique...
From: "Lars Huttar" <lars_huttar@xxxxxxx>
Date: Wed, 18 Jun 2003 13:47:28 -0500
> Thanks to those who replied! 
> 
> Oh well, Muenchian technique and the common way outputs the 
> different result which seems they both giving unique 
> solutions, but the one that Muenchian has a shorter list than 
> the other one.

Shorter indeed: consisting only of "A". See comments below for why.
The other one gives the correct list, "ABCDE".

> But I really want to use Muenchian due to the 
> large amount of the nodes. Anything wrong with my code? Thanks a lot!!
> 
> <?xml version="1.0" encoding="UTF-8"?>
> <xsl:transform 
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; version="1.1">

Umm... version 1.1?  Is this legal?
I guess so... msxsl and saxon didn't complain.

> <xsl:key name="solution-key" match="metadata" use="solution" />	
> 
> <xsl:template match="report">
> 	<!-- using Muenchian technique to display a list of 
> unique solutions -->
> 	<xsl:apply-templates select="item">
> 		<xsl:sort select="metadata/solution/."/>
> 	</xsl:apply-templates>

[snip]
 
> <xsl:template match="item">
> 	<xsl:for-each select="metadata[generate-id(.) = 
> generate-id(key('solution-key', solution)[1])]">
> 		<xsl:value-of select="solution/."/>
> 	</xsl:for-each>
> </xsl:template>

What this does is, for each <item>, select all <metadata>
children (of which there is only one possible, by the way)
and ask whether it is the same as the first <metadata> returned
by the key() of all its <solution> children, and if so,
print the value of its *first* <solution> child.
So it's kind of mixed up.

I think what you really want to do is apply templates
to <solution>s instead of <item>s, and modify your select=
like this:

    <xsl:if test="generate-id(..) = generate-id(key('solution-key', .)[1])">

(the xsl:if is basically equivalent to a xsl:for-each, since we're
just testing one node, the context node).

So the whole thing would be:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
	<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

  <xsl:key name="solution-key" match="metadata" use="solution" />	
  
  <xsl:template match="report">
  	<!-- using Muenchian technique to display a list of unique solutions -->
  	<xsl:apply-templates select="item/metadata/solution">
  		<xsl:sort select="."/>
  	</xsl:apply-templates>       
  </xsl:template>
  
  <!-- Here I'm assuming, as I think you were, that each solution
       is unique within its parent <metadata>. So we can group
       <solution>s by their parent. Otherwise you'd use a different
       key that mapped <solution> text values to <solution> nodes. -->
  <xsl:template match="solution">
    <xsl:if test="generate-id(..) = generate-id(key('solution-key', .)[1])">
      <xsl:value-of select="." />
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

HTH,
Lars


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread