Re: [xsl] Trying to pull of a double Muenchian

Subject: Re: [xsl] Trying to pull of a double Muenchian
From: Wendell Piez <wapiez@xxxxxxxxxxxxxxxx>
Date: Tue, 28 Feb 2006 12:33:06 -0500

Muenchian grouping gets complex and ugly (or: uglier ;-) when it goes to multiple levels, because keys have document-wide scope. So in your case, for example, to avoid the problem you describe, the second key would have to be a "compound" key, as in

<xsl:key name="product" match="/csv_data_records/record"
  use="concat(item[2], item[4])"/>

and called accordingly.

However, there may be other, nicer methods. See the approach Ken Holman has tried to instill in our minds, variable-based grouping, as described at

Basically the idea is to use variables to collect together all the nodes to be grouped, and to select from those variables to collect your subgroups. It goes to multiple levels much more nicely.

Note that construing Ken's code does require understanding that


is the same as


Another alternative that may be available to you: use XSLT 2.0.


At 09:03 AM 2/28/2006, you wrote:
I have found various suggestions on this list, and links to more
explanatory pages describing the Muenchian technique to sort or group
xml data.

However, I am trying to do a kind of a double Muenchian, which is to
group xml data i two levels. but there must be something i am missing,
because it is not working as I expected.

The xml is the kind of standard data format:
   <item name="1">data 1</item>
   <item name="2">data 2</item>
   <item name="3">data 3</item>
   <item name="1">data 1</item>
   <item name="2">data 2</item>
   <item name="3">data 3</item>

My real xslt look like this:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="";>
<xsl:output method="xml" version="1.0" encoding="ISO-8859-1" indent="yes"/>
<!-- V A R I A B L E S -->
<xsl:key name="suplier" match="/csv_data_records/record" use="item[2]"/>
<xsl:key name="product" match="/csv_data_records/record" use="item[4]"/>
<xsl:template match="/">
<xsl:template match="csv_data_records">
<xsl:for-each select="record[count(. | key('suplier', item[2])[1])=1]">
<xsl:attribute name="name"><xsl:value-of select="item[3]"/></xsl:attribute>
<xsl:attribute name="value"><xsl:value-of select="item[2]"/></xsl:attribute>
<xsl:for-each select="key('suplier', item[2])">
<xsl:attribute name="group"><xsl:value-of
<xsl:for-each select="key('product', item[4])">

<xsl:value-of select="item[1]"/>

<xsl:value-of select="item[6]"/>

<xsl:value-of select="item[7]"/>

It seems that I am not getting the second grouping on the items right.
They are grouped all right, but they are repeated x times the node

What have I missed out, or what am I doing wrong here.


Wendell Piez                            mailto:wapiez@xxxxxxxxxxxxxxxx
Mulberry Technologies, Inc.      
17 West Jefferson Street                    Direct Phone: 301/315-9635
Suite 207                                          Phone: 301/315-9631
Rockville, MD  20850                                 Fax: 301/315-8285
  Mulberry Technologies: A Consultancy Specializing in SGML and XML

Current Thread