Re: [xsl] flat structure to deep structure in a smart way

Subject: Re: [xsl] flat structure to deep structure in a smart way
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Fri, 24 Sep 2004 22:03:27 +0100
Hi Jozef,

Now I got a bit stuck. Under the A3 I need to group the B-elements
again. How do I do that ?

When you do Muenchian grouping with more than one level, the keys for the extra levels need to incorporate information about the previous levels. Otherwise they retrieve *all* the records with the particular value, rather than just those within the group you're interested in.


So to group the Bs, you need a key that looks like:

<xsl:key name="B-key" match="line"
  use="concat(item[@itemcount = 1], '+', item[@itemcount = 2])" />

The lines will then be indexed by B-key as "A1+B1", "A1+B22" etc. Note that you should use something appropriate for the separator: something that doesn't appear within the values of A or B.

Then you do something along the lines of:

<result>
<xsl:for-each select="line[count(. | key('A-key', item[@itemcount = 1])[1]) = 1]">
<xsl:variable name="A-value" select="item[@itemcount = 1]" />
<xsl:variable name="A-group" select="key('A-key', $A-value)" />
<A value="{$A-value}">
<xsl:for-each select="$A-group[count(. | key('B-key', concat($A-value, '+', item[@itemcount = 2]))[1]) = 1]">
<xsl:variable name="B-value" select="item[@itemcount = 2]" />
<xsl:variable name="B-group"
select="key('B-key', concat($A-value, '+', $B-value))" />
<B value="{$B-value}">
...
</B>
</xsl:for-each>
</A>
</xsl:for-each>
</result>


The more levels you have, the more tedious it becomes. XSLT 2.0 makes it quite a bit easier:

  <result>
    <xsl:for-each-group select="line"
                        group-by="item[@itemcount = 1]">
      <A value="{current-grouping-key()}">
        <xsl:for-each-group select="current-group()"
                            group-by="item[@itemcount = 2]">
          <B value="{current-grouping-key()}">
            ...
          </B>
        </xsl:for-each-group>
      </A>
    </xsl:for-each-group>
  </result>

Cheers,

Jeni
--
Jeni Tennison
http://www.jenitennison.com

Current Thread