Re: [xsl] using xsl:for-each-group, grouping by child nodes?

Subject: Re: [xsl] using xsl:for-each-group, grouping by child nodes?
From: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx>
Date: Sat, 04 Oct 2008 09:57:19 -0400
At 2008-10-04 17:38 +1000, Eric Scheid wrote:
I have export data that looks like this:
...
I'm trying to transform it into this:
...
.. so naturally I thought of using for-each-group, only problem is I can't
find any examples which shows how to group-by using values in the child
nodes

Your words reveal what is required: "using values in child nodes".


... so I don't know if this is even possible, let alone exactly how to
specify it. I've tried a few different things to no avail.

I see two grouping levels, first by team and then by position.


Is this even possible?

I hope the example below helps.


. . . . . . . . . Ken

T:\ftemp>type eric.xml
<RESULTSET FOUND="6">
    <ROW MODID="3" RECORDID="1">
        <COL><DATA>joe</DATA></COL>
        <COL><DATA>2</DATA></COL>
        <COL><DATA>pitcher</DATA></COL>
        <COL><DATA>ny</DATA></COL>
        <COL><DATA>mets</DATA></COL>
    </ROW>
    <ROW MODID="3" RECORDID="2">
        <COL><DATA>mark</DATA></COL>
        <COL><DATA>11</DATA></COL>
        <COL><DATA>outfielder</DATA></COL>
        <COL><DATA>ny</DATA></COL>
        <COL><DATA>mets</DATA></COL>
    </ROW>
    <ROW MODID="3" RECORDID="3">
        <COL><DATA>jane</DATA></COL>
        <COL><DATA>13</DATA></COL>
        <COL><DATA>outfielder</DATA></COL>
        <COL><DATA>ny</DATA></COL>
        <COL><DATA>cubs</DATA></COL>
    </ROW>
    <ROW MODID="3" RECORDID="4">
        <COL><DATA>mike</DATA></COL>
        <COL><DATA>7</DATA></COL>
        <COL><DATA>outfielder</DATA></COL>
        <COL><DATA>ny</DATA></COL>
        <COL><DATA>mets</DATA></COL>
    </ROW>
</RESULTSET>

T:\ftemp>type eric.xsl
<?xml version="1.0" encoding="US-ASCII"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                version="2.0">

<xsl:output method="text"/>

<xsl:template match="/">
  <!--group first by team; using a key of two parts with an unlikely
      character in between to avoid any ambiguous concatenations-->
  <xsl:for-each-group select="/*/ROW"
                      group-by="concat(COL[4]/DATA,'&#xd;',COL[5]/DATA)">
    <xsl:if test="position()>1"><xsl:text>&#xa;</xsl:text></xsl:if>
    Team: <xsl:value-of select="concat(COL[5]/DATA,', ',COL[4]/DATA)"/>
    <!--now group by position; reflecting plural where applicable-->
    <xsl:for-each-group select="current-group()" group-by="COL[3]/DATA">
      <xsl:text>&#xa;       </xsl:text>
      <xsl:value-of select="concat( COL[3]/DATA,
                    if (count(current-group())>1) then 's' else '',':')"/>
      <!--show all in the position-->
      <xsl:for-each select="current-group()">
        <xsl:text>&#xa;           </xsl:text>
        <xsl:value-of select="concat( COL[1]/DATA,', ',COL[2]/DATA )"/>
      </xsl:for-each>
    </xsl:for-each-group>
  </xsl:for-each-group>
</xsl:template>

</xsl:stylesheet>
T:\ftemp>xslt2 eric.xml eric.xsl con

    Team: mets, ny
       pitcher:
           joe, 2
       outfielders:
           mark, 11
           mike, 7

    Team: cubs, ny
       outfielder:
           jane, 13
T:\ftemp>


-- Upcoming XSLT/XSL-FO hands-on courses: Wellington, NZ 2009-01 Training tools: Comprehensive interactive XSLT/XPath 1.0/2.0 video Video sample lesson: http://www.youtube.com/watch?v=PrNjJCh7Ppg Video course overview: http://www.youtube.com/watch?v=VTiodiij6gE G. Ken Holman mailto:gkholman@xxxxxxxxxxxxxxxxxxxx Crane Softwrights Ltd. http://www.CraneSoftwrights.com/s/ Male Cancer Awareness Nov'07 http://www.CraneSoftwrights.com/s/bc Legal business disclaimers: http://www.CraneSoftwrights.com/legal

Current Thread