RE: [xsl] Grouping upon various attribute values

Subject: RE: [xsl] Grouping upon various attribute values
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Wed, 16 Aug 2006 14:55:08 +0100
There's no direct support for composite grouping keys in xsl:for-each-group.
The simplest solution is to form the composite key yourself. The following
looks promising:

group-by="string-join(@*, '|')" 

but is wrong, because the result depends on attribute order. If you know
what attributes you're interested in, use

group-by="concat(@aufAttribut, '|', @typ, '|', @wertStruktur...)"

Alternatively:

group-by="f:all-attributes(.)"

<xsl:function name="f:all-attributes" as="xs:string">
  <xsl:param name="node" as="element()"/>
  <xsl:value-of>
    <xsl:for-each select="$node/@*">
      <xsl:sort select="namespace-uri()"/>
      <xsl:sort select="local-name()"/>
      <xsl:value-of select="."/>
      <xsl:text>|</xsl:text>
    </xsl:for-each>
  </xsl:value-of>
</xsl:function>

The other approach is nested groups:

<xsl:for-each-group group-by="@aufAttribute">
  <xsl:for-each-group select="current-group()" select="@typ">
    <xsl:for-each-group select="current-group()" select="@wertStruktur">
      ...

Michael Kay
http://www.saxonica.com/


> -----Original Message-----
> From: lawrence.michel@xxxxxxx [mailto:lawrence.michel@xxxxxxx] 
> Sent: 16 August 2006 14:26
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] Grouping upon various attribute values
> 
> Hi all,
> 
> I have a little problem, which gives me a bit headache at the moment.
> Maybe you could help me solve it :
> 
> Here the given XML :
> 
> 		<produktenZumAnalysieren>
> 			<gesamtMenge>
> 				<filter aufAttribut="Name_Stat"
> typ="diskret" wertStruktur="baum" wert="BP"/>
> 				<filter aufAttribut="FrankaturArt"
> typ="diskret" wertStruktur="genau" wert="PP"/>
> 			</gesamtMenge>
> 		</produktenZumAnalysieren>
> 		<produktenZumAnalysieren>
> 			<gesamtMenge>
> 				<filter aufAttribut="Name_Stat"
> typ="diskret" wertStruktur="baum" wert="BP"/>
> 				<filter aufAttribut="FrankaturArt"
> typ="diskret" wertStruktur="genau" wert="PP"/>
> 			</gesamtMenge>
> 		</produktenZumAnalysieren>
> 		<produktenZumAnalysieren>
> 			<gesamtMenge>
> 				<filter aufAttribut="Name_Stat"
> typ="diskret" wertStruktur="baum" wert="BP"/>
> 				<filter aufAttribut="Gewicht"
> typ="interval" wert_Ab="1" wert_Bis="100"/>  //<- Careful 
> here, there is a new set of attributes
> 			</gesamtMenge>
> 	</produktenZumAnalysieren>
> 
> As you can see, there are three "gesamtMenge" elements, each 
> in its own "ProduktZumAnalysieren" element.
> 
> Now, I would like to apply a for-each-group loop on them :
> 
> 	<xsl:for-each-group select="produktenZumAnalysieren"
> group-by="gesamtMenge/filter/@* (KICKME HERE)">
> 
> That is, the grouping key isn't doing what I expect: I need 
> to have all attributes taken in consideration for grouping 
> the required elements. In this example, I should have two 
> distinctive groups
> 
> Any help would be really greatfull ;-)
> 
> Cheers
> 
> Lawrence Michel, Bern, Switzerland

Current Thread