[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: Group elements by two keys

Subject: Re: Group elements by two keys
From: Martin Honnen <Martin.Honnen@xxxxxx>
Date: Mon, 21 Sep 2009 14:31:04 +0200
Re:  Group elements by two keys
Jens Reese wrote:

The desired output is:
TEST
COM
N1-N_One, N2-N_Two, N3-N_Three
Info1-1A
N1-N_One, N2-N_Two
Info3-3B

RAF
N1-N_One, N4-N_Four
Info2-2A
N2-N_Two, N4-N_Four
Info5-2A Info4-4B

As you can see the first group is the value of the fir/info/type element, the second group title should be a combined string created out of the data of itemA elements of a fir element.

I'd like to know if this is possible and if yes how.

This is straightforward with XSLT 2.0:


<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="2.0">

  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="/">
    <html lang="en">
      <head>
        <title>Test</title>
      </head>
      <body>
        <h1>Test</h1>
        <xsl:apply-templates/>
      </body>
    </html>
  </xsl:template>

<xsl:template match="test">
<xsl:for-each-group select="fir/info" group-by="typ">
<xsl:value-of select="current-grouping-key()"/>
<br/>
<xsl:for-each-group select="current-group()" group-by="string-join(itemA/concat(id, '-', name), ', ')">
<xsl:value-of select="current-grouping-key()"/>
<br/>
<xsl:value-of select="current-group()/concat(id, '-', num, serie)" separator=" "/>
<br/>
</xsl:for-each-group>
<br/><br/>
</xsl:for-each-group>
</xsl:template>


</xsl:stylesheet>

With XSLT 1.0 you would need two steps I think, the first creating a temporary result with an attribute or element having the combined value, then you can define a key on the temporary result. If you want to perform two steps in one stylesheet then you need to use exsl:node-set or similar:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:exsl="http://exslt.org/common"
  exclude-result-prefixes="exsl"
  version="1.0">

  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:key name="k1" match="fir/info" use="typ"/>
  <xsl:key name="k2" match="group/info" use="concat(../@key, '|', @key)"/>

  <xsl:template match="/">
    <html lang="en">
      <head>
        <title>Test</title>
      </head>
      <body>
        <h1>Test</h1>
        <xsl:apply-templates/>
      </body>
    </html>
  </xsl:template>

<xsl:template match="test">
<xsl:variable name="group-rtf">
<xsl:for-each select="fir/info[generate-id() = generate-id(key('k1', typ)[1])]">
<group key="{typ}">
<xsl:for-each select="key('k1', typ)">
<xsl:copy>
<xsl:attribute name="key">
<xsl:for-each select="itemA">
<xsl:value-of select="id"/>-<xsl:value-of select="name"/>
<xsl:if test="position() != last()">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:attribute>
<xsl:copy-of select="node()"/>
</xsl:copy>
</xsl:for-each>
</group>
</xsl:for-each>
</xsl:variable>
<xsl:for-each select="exsl:node-set($group-rtf)/group">
<xsl:value-of select="@key"/>
<br/>
<xsl:for-each select="info[generate-id() = generate-id(key('k2', concat(../@key, '|', @key))[1])]">
<xsl:value-of select="@key"/>
<br/>
<xsl:for-each select="key('k2', concat(../@key, '|', @key))">
<xsl:value-of select="concat(id, '-', num, serie)"/>
<xsl:if test="position() != last()"><xsl:text> </xsl:text></xsl:if>
</xsl:for-each>
<br/>
</xsl:for-each>
</xsl:for-each>
</xsl:template>


</xsl:stylesheet>

--

	Martin Honnen
	http://msmvps.com/blogs/martin_honnen/

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.