[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] Fwd: level grouping problem


Subject: Re: [xsl] Fwd: level grouping problem
From: "Maria Shvedova" <shvedova.maria@xxxxxxxxx>
Date: Mon, 10 Sep 2007 11:10:46 +1000

Ken,
The solution that you've provided does exactly what is needed!

Regards,
Maria

On 9/6/07, G. Ken Holman <gkholman@xxxxxxxxxxxxxxxxxxxx> wrote:
> At 2007-09-06 12:24 +1000, Maria Shvedova wrote:
> >My appologies in advance for the possible incorrect use of
> >terminology, I'm still new to xslt.
>
> It sure sounds like you know what you are talking about.
>
> >I have an xml file that looks like that:
> >...
> >and the output that I'm trying to achieve is the following:  (the
> >grouping needs to occur within each <reference> tag,  i.e. I need to
> >get)
> >...
> >what is happening instead, though, is that elements are being grouped
> >together, so the output that I get is:
>
> Yes, because you've used the XSLT 1.0 document-wide grouping method
> based on keys.
>
> >here is the stylesheet that I'm using:
> ><xsl:stylesheet xmlns:xsl=" http://www.w3.org/1999/XSL/Transform "
> >version="1.0">
> >   <xsl:key name="det" match="/export/references/reference/detail"
> > use="@name"/>
> >   <xsl:template match="/export/references">
> >       <html>
> >       <body>
> >           <table>
>
> I'm not sure what you are doing with the <table> element so it is not
> in my solutions below.
>
> >           <xsl:apply-templates select="reference"/>
> >           </table>
> >       </body>
> >       </html>
> >   </xsl:template>
> >
> >   <xsl:template match="reference">
> >       <xsl:for-each
> >select="detail[generate-id(.)=generate-id(key('det', @name))]/@name">
>
> You've implemented a classic application of the Muenchian method,
> which is just fine for document-wide grouping, but your sub-document
> grouping can get awkward when using keys.  Below I've used a
> variable-based method for XSLT 1.0 for sub-document grouping.
>
> I wasn't exactly sure where you were going with the sorting, so I
> sorted by @name, and then I sorted the group by title.  You can
> remove what you don't need.
>
> >Any help would me much appreciated!! its probably obvious, but I've
> >been staring at it for hours....
> >(The  parser we have can work with both xslt  1.0 and 2.0)
>
> Then I suggest you switch to XSLT 2.0 which has built-in facilities
> for grouping.  It has greatly simplified my teaching of this requirement.
>
> I hope this helps.
>
> . . . . . . . . . . . . . Ken
>
>
> T:\ftemp>type maria.xml
> <export>
>      <references>
>          <reference>
>              <detail name="Detail1">
>                  <title>Detail 1 text</title>
>              </detail>
>              <detail name="Detail2">
>                  <title>Detail2 text</title>
>              </detail>
>              <detail name="Detail2">
>                  <title>Detail2 text</title>
>              </detail>
>          </reference>
>          <reference>
>              <detail name="Detail1">
>                  <title>Detail 1 text</title>
>              </detail>
>              <detail name="Detail2">
>                  <title>Detail2 text</title>
>              </detail>
>              <detail name="Detail2">
>                  <title>Detail2 text</title>
>              </detail>
>          </reference>
>      </references>
> </export>
>
> T:\ftemp>type maria.xsl
> <?xml version="1.0" encoding="US-ASCII"?>
> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>                  version="1.0">
>
> <xsl:output indent="yes"/>
>
> <xsl:template match="/">
>    <html>
>      <body>
>        <xsl:apply-templates select="export/references/reference"/>
>      </body>
>    </html>
> </xsl:template>
>
> <xsl:template match="reference">
>    <!--put what is being grouped in a variable-->
>    <xsl:variable name="details" select="detail"/>
>    <!--walk through the variable-->
>    <xsl:for-each select="detail">
>      <xsl:sort select="@name"/>
>      <!--act on the first in document order-->
>      <xsl:if test="generate-id(.)=
>                    generate-id($details[@name=current()/@name][1])">
>        <h2>
>          <xsl:value-of select="@name"/>
>        </h2>
>        <!--revisit all-->
>        <xsl:for-each select="$details[@name=current()/@name]">
>          <xsl:sort select="title"/>
>          <i><xsl:value-of select="title"/></i>
>          <br/>
>        </xsl:for-each>
>      </xsl:if>
>    </xsl:for-each>
> </xsl:template>
>
> </xsl:stylesheet>
> T:\ftemp>call xslt maria.xml maria.xsl maria.htm
>
> T:\ftemp>type maria.htm
> <html>
>     <body>
>        <h2>Detail1</h2><i>Detail 1
> text</i><br><h2>Detail2</h2><i>Detail2 text</i><br><i>Detail2
> text</i><br><h2>Detail1</h2><i>Detail 1
> text</i><br><h2>Detail2</h2><i>Detail2 text</i><br><i>Detail2
> text</i><br></body>
> </html>
> T:\ftemp>type maria2.xsl
> <?xml version="1.0" encoding="US-ASCII"?>
> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>                  version="2.0">
>
> <xsl:output indent="yes"/>
>
> <xsl:template match="/">
>    <html>
>      <body>
>        <xsl:apply-templates select="export/references/reference"/>
>      </body>
>    </html>
> </xsl:template>
>
> <xsl:template match="reference">
>    <xsl:for-each-group select="detail" group-by="@name">
>      <xsl:sort select="@name"/>
>      <h2>
>        <xsl:value-of select="@name"/>
>      </h2>
>      <xsl:for-each select="current-group()">
>        <xsl:sort select="title"/>
>        <i><xsl:value-of select="title"/></i>
>        <br/>
>      </xsl:for-each>
>    </xsl:for-each-group>
> </xsl:template>
>
> </xsl:stylesheet>
> T:\ftemp>call xslt2 maria.xml maria2.xsl maria2.htm
> <html>
>     <body>
>        <h2>Detail1</h2><i>Detail 1
> text</i><br><h2>Detail2</h2><i>Detail2 text</i><br><i>Detail2
> text</i><br><h2>Detail1</h2><i>Detail 1
> text</i><br><h2>Detail2</h2><i>Detail2 text</i><br><i>Detail2
> text</i><br></body>
> </html>
>
>
> --
> Upcoming public training: XSLT/XSL-FO Sep 10, UBL/code lists Oct 1
> World-wide corporate, govt. & user group XML, XSL and UBL training
> RSS feeds:     publicly-available developer resources and training
> G. Ken Holman                 mailto:gkholman@xxxxxxxxxxxxxxxxxxxx
> Crane Softwrights Ltd.          http://www.CraneSoftwrights.com/s/
> Box 266, Kars, Ontario CANADA K0A-2E0    +1(613)489-0999 (F:-0995)
> Male Cancer Awareness Jul'07  http://www.CraneSoftwrights.com/s/bc
> Legal business disclaimers:  http://www.CraneSoftwrights.com/legal


Current Thread
Keywords