xsl-list
[Top] [All Lists]

RE: grouping by unique...

2003-06-18 11:47:28
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



<Prev in Thread] Current Thread [Next in Thread>