Re: [xsl] Question about grouping

Subject: Re: [xsl] Question about grouping
From: Mukul Gandhi <gandhi.mukul@xxxxxxxxx>
Date: Sat, 25 Sep 2010 08:52:22 +0530
Here's another 1.0 solution for this problem (written a bit
differently but essentially does similar to the other generate-id
solution):

(I wrote this hours ago, and didn't post it as I saw other reasonable
solutions :) posting this anyway.)

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

  <xsl:output method="xml" indent="yes" />

  <xsl:key name="authorgroup" match="book" use="@author" />

  <xsl:template match="doc">
	 <report>
	    <xsl:for-each select="book[generate-id(.) =
generate-id(key('authorgroup', @author)[1])]">
		   <author name="{@author}">
		        <xsl:apply-templates select="key('authorgroup', @author)"
mode="groupByAuthor" />
		   </author>
		</xsl:for-each>
	 </report>
  </xsl:template>

  <xsl:template match="book" mode="groupByAuthor">
      <title>
	   <xsl:value-of select="@title" />
      </title>
  </xsl:template>

</xsl:stylesheet>

Here are probably the reasons why I organized the stylesheet as presented:
1. Writing all of the logic in one template (say in root template,
using a for loop and all), is a monolithic design, and parts of
stylesheet logic are not reusable (I believe, re-usability of logic in
any program is useful for reasons best known to all of us
programmers!).

So I created a template "book" with a mode.

2. I thought using mode was useful, since then the template for "book"
cannot (or would be really really difficult) be invoked accidentally
by another invocation of this template, like for example:
<xsl:apply-templates select="book" /> (which is the side effect I
wanted to avoid with modes!).


PS: I do like 2.0 for-each-group because it doesn't require XSLT keys
for grouping (this is useful because with XSLT 2.0 we don't have to
think about design of key's [a real static wiring of logic in our
brains, which I don't like!] in a stylesheet for grouping), and
grouping with for-each-group can be nested at arbitrary levels, which
is really nice :) Arbitrary nesting of groups in 1.0 get's almost
undoable beyond a certain point. So if we have scale our groups in
XSLT stylesheets, using XSLT 2.0 (and 2.1/3.0 in future :)) is the
only way going forward.

On Fri, Sep 24, 2010 at 7:20 AM, David Frey <dpfrey@xxxxxxx> wrote:
> I have an XSLT problem that I haven't been able to figure out. B The
example
> below is essentially the simplest version of the problem I have
encountered.
>
> Say you have a document like this:
>
> <doc>
> B <book title="aaa" author="jones"/>
> B <book title="bbb" author="smith"/>
> B <book title="ccc" author="douglas"/>
> B <book title="ddd" author="jones"/>
> B <book title="eee" author="jones"/>
> B <book title="fff" author="douglas"/>
> B <book title="ggg" author="smith"/>
> </doc>
>
>
> How can you produce a document like this?:
>
> <report>
> B <author name="jones">
> B  B  B  B <title>aaa</title>
> B  B  B  B <title>ddd</title>
> B  B  B  B <title>eee</title>
> B </author>
> B <author name="smith">
> B  B  B  B <title>bbb</title>
> B  B  B  B <title>ggg</title>
> B </author>
> B <author name="douglas">
> B  B  B  B <title>bbb</title>
> B  B  B  B <title>fff</title>
> B </author>
> </report>
>
> Restrictions:
> - Only XSLT 1.0
> - You can't hard-code the names of the books or the authors in the XSLT.
>
>
> Thanks,
> Dave




--
Regards,
Mukul Gandhi

Current Thread