Re: [xsl] Grouping & Muenchian Method Question

Subject: Re: [xsl] Grouping & Muenchian Method Question
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Wed, 3 Jan 2001 10:20:15 +0000
Hi Albert,

[The jeni.tennison@xxxxxxxxxxxxxxxx address doesn't work any more -
use mail@xxxxxxxxxxxxxxxx instead.  Thanks.]

> However, if I want to do second level grouping with the key() and
> generate-id() again, unexpected result come up.

When you're doing multiple levels of grouping, you have to keep in
mind that the lower levels are still grouped according to the higher
levels.  In your example, you want to group first by ServiceCode and
then by ExchangeName and ExchangeCode combined.  When you are within
the group that has a ServiceCode of M, you only want to consider those
SettleItems that have a ServiceCode of M - you want to ignore all the
others.

Using the Muenchian method, you use the fact that you can get unique
values for a particular property by looking at the first item
from the list returned by the key indexed on that property.  In your
case, you can get unique values for the ExchangeName+ExchangeCode
combination by looking at the first SettleItem returned by the key
with a particular ExchangeName+ExchangeCode combination.  However,
this first SettleItem might be in either of the ServiceCode groups -
you don't know which.  If it's in one of the *other* ServiceCode
groups, then that particular value will be ignored, which means you
won't get all the values, which is why you've got some rows missing in
your table.

In practical terms using the Muenchian grouping method, this means
that you should build the hierarchy of keys to reflect the grouping
hierarchy that you're after.  The first key is for the first level of
grouping, and just involves the ServiceCode:

<xsl:key name="service_row"
         match="SetDailySetRpt:SettleItem"
         use="SetDailySetRpt:ServiceCode" />

The second key is for the second level of grouping.  This needs to
involve the ServiceCode because you're only going to be interested in
one particular ServiceCode group when you start grouping at this
level, as well as the other things you want to group by:

<xsl:key name="exchange"
         match="SetDailySetRpt:SettleItem"
         use="concat(SetDailySetRpt:ServiceCode, ' ',
                     SetDailySetRpt:ExchangeName, ' ',
                     SetDailySetRpt:ExchangeCode)" />

With the key set up like this, the second level of grouping can be
done with something like:

  <xsl:variable
      name="service_items"
      select="key('service_rows', SetDailySetRpt:ServiceCode)" />
  <xsl:for-each
      select="$service_items[generate-id() =
                             generate-id(
                               key('exchange',
                                   concat(SetDailySetRpt:ServiceCode,
                                          ' ',
                                          SetDailySetRpt:ExchangeName,
                                          ' ',
                                          SetDailySetRpt:ExchangeCode))[1])]">
    <xsl:value-of select="SetDailySetRpt:ExchangeName" />
    <xsl:text> </xsl:text>
    <xsl:value-of select="SetDailySetRpt:ExchangeCode" />&nl;
  </xsl:for-each>

The same principal applies if you want to group down further levels:
at each level, the key has to include all the items that made up the
keys from higher levels.  So the key for the next level of grouping in
your example has to include the ServiceCode, ExchangeName and
ExchangeCode as well as whatever you want to group on next.

I hope that helps,

Jeni

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



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


Current Thread