This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: Multi-level grouping problem. MSXML bug, maybe?
- From: Jeni Tennison <jeni at jenitennison dot com>
- To: mpfingstler at triseptsolutions dot com
- Cc: XSL-List at lists dot mulberrytech dot com
- Date: Thu, 9 May 2002 10:10:02 +0100
- Subject: Re: [xsl] Multi-level grouping problem. MSXML bug, maybe?
- Organization: Jeni Tennison Consulting Ltd
- References: <993DAE6342A5D41185190001FAFFF4B102B859EB@EXCHANGE04>
- Reply-to: xsl-list at lists dot mulberrytech dot com
Hi Mark,
> I want the output to look like:
>
> <?xml version="1.0" encoding="iso-8859-1"?>
> <CS>
> <Co Type="F" SubType="S">
> <DG Code="V" />
> <DG Code="F" />
> </Co>
> <Co Type="F" SubType="T">
> <DG Code="V" />
> </Co>
> </CS>
>
> That is, I'm grouping by TYPE, SUB_TYPE, and D_CODE.
Yes, you've got two levels of grouping: one by TYPE and SUB_TYPE, and
one by D_CODE. Your key for grouping by TYPE and SUB_TYPE looks fine:
> <xsl:key name="row-by-type-subtype" match="row"
> use="concat(TYPE/@value, '|', SUB_TYPE/@value)"/>
But your key for grouping by D_CODE is off. You have:
> <xsl:key name="d-by-type-subtype" match="D_CODE"
> use="concat(../TYPE/@value, '|', ../SUB_TYPE/@value)"/>
This groups the D_CODE elements by their row's TYPE and SUB_TYPE; in
other words, it does exactly the same as the first key, except
grouping the D_CODE elements rather than the rows.
You want to group the *rows* by their D_CODE values. And because it's
the second level in the grouping, you need to incorporate the TYPE and
SUB_TYPE into that as well. So the key should look like:
<xsl:key name="row-by-d-code" match="row"
use="concat(TYPE/@value, '|', SUB_TYPE/@value, '|', D_CODE/@value)"/>
Then you just do what you're doing, but use this key to filter the
rows with a particular TYPE and SUB_TYPE down to those with a unique
D_CODE as well:
<xsl:for-each select="/recordset/row[count(. |
key('row-by-type-subtype', concat(TYPE/@value, '|', SUB_TYPE/@value))[1]) = 1]">
<xsl:variable name="type" select="TYPE/@value"/>
<xsl:variable name="subtype" select="SUB_TYPE/@value"/>
<xsl:variable name="type-subtype"
select="concat($type, '|', $subtype)" />
<Co Type="{$type}" SubType="{$subtype}">
<xsl:for-each select="key('row-by-type-subtype', $type-subtype)
[count(.|key('row-by-d-code',
concat($type-subtype, '|', D_CODE/@value))[1])=1">
<DG Code="{D_CODE/@value}" />
</xsl:for-each>
</Co>
</xsl:for-each>
----
The XSLT 2.0 version:
<xsl:for-each-group select="/recordset/row"
group-by="concat(TYPE/@value, '|', SUB_TYPE/@value)">
<Co Type="{TYPE/@value}" SubType="{SUB_TYPE/@value}">
<xsl:for-each-group select="current-group()"
group-by="D_CODE/@value">
<DG Code="{D_CODE/@value}" />
</xsl:for-each-group>
</Co>
</xsl:for-each-group>
Cheers,
Jeni
---
Jeni Tennison
http://www.jenitennison.com/
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list