RE: [xsl] grouping/position problem

Subject: RE: [xsl] grouping/position problem
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Sun, 24 Apr 2005 14:10:23 +0100
In effect you need to sort by year before you group by year, and set
shorten-author to true for all but the first item in the list of items for
an author in year order.

Something like:

     <xsl:template match="list" mode="sort_author-year">
       <xsl:for-each-group select="item" group-by="@author">
         <xsl:sort select="current-grouping-key()"/>
         <xsl:variable name="items-for-author-sorted-by-year
as="element(item)*">
           <xsl:perform-sort select="current-group()">
             <xsl:sort select="@year"/>
           </xsl:perform-sort>
         <xsl:variable>
         <xsl:variable name="first-item-for-author" as="element(item)"
            select="$items-for-author-sorted-by-year[1]"/>
         <xsl:for-each-group select="$items-for-author-sorted-by-year"
group-adjacent="@year"
           <xsl:for-each select="current-group()">
 	        <xsl:variable name="year">
                <xsl:value-of select="current-grouping-key()"/>
 	          <xsl:if test="last() > 1">
 	            <xsl:number value="position()" format="a"/>
 	          </xsl:if>
 	        </xsl:variable>
              <xsl:variable name="shorten-author" as="xs:boolean"
                 select="not(. is $first-item-for-author)" />

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


> -----Original Message-----
> From: Bruce D'Arcus [mailto:bdarcus@xxxxxxxxx] 
> Sent: 24 April 2005 00:21
> To: XSL-List@xxxxxxxxxxxxxxxxxxxxxx
> Subject: Re: [xsl] grouping/position problem
> 
> 
> Actually, I need to correct two things on my reply to Mike; first the 
> template needs to put the year variable within the year-grouped 
> for-each (it was outside the for-each).  So:
> 
>     <xsl:template match="list" mode="sort_author-year">
>       <xsl:for-each-group select="item" group-by="@author">
>         <xsl:sort select="current-grouping-key()"/>
>         <xsl:for-each-group select="current-group()" group-by="@year">
>           <xsl:sort select="current-grouping-key()" />
>           <xsl:for-each select="current-group()">
> 	   <xsl:variable name="year">
>                <xsl:value-of select="current-grouping-key()"/>
> 	       <xsl:if test="last() > 1">
> 	         <xsl:number value="position()" format="a"/>
> 	       </xsl:if>
> 	   </xsl:variable>
>             <xsl:variable name="author-position" select="position()"/>
>             <xsl:variable name="shorten-author" 
> as="xs:boolean"select="$author-position > 1" />
>             <xsl:apply-templates select=".">
>               <xsl:with-param name="year" select="$year"/>
>               <xsl:with-param 
> name="shorten-author"select="$shorten-author"/>
>             </xsl:apply-templates>
>           </xsl:for-each>
>         </xsl:for-each-group>
>       </xsl:for-each-group>
>     </xsl:template>
> 
> Therefore this is wrong:
> 
> > ... here's the expected result:
> >
> > <result>
> >    <item>
> >       <shorten-author>false</shorten-author>
> >       <year>2001a</year>
> >    </item>
> >    <item>
> >       <shorten-author>true</shorten-author>
> >       <year>2001a</year>
> >    </item>
> >    <item>
> >       <shorten-author>true</shorten-author>
> >       <year>2002b</year>
> >    </item>
> > </result>
> 
> It should be:
> 
> <result>
>     <item>
>        <shorten-author>false</shorten-author>
>        <year>2001a</year>
>     </item>
>     <item>
>        <shorten-author>true</shorten-author>
>        <year>2001a</year>
>     </item>
>     <item>
>        <shorten-author>true</shorten-author>
>        <year>2002</year>
>     </item>
> </result>
> 
> Note the last year.
> 
> Bruce

Current Thread