RE: [xsl] for-each-group usage

Subject: RE: [xsl] for-each-group usage
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Tue, 6 Mar 2007 23:46:56 -0000
The group-by and order-by expressions both need to be relative to the nodes
being grouped. That is, you want the group-by expression to be "d" rather
than "doc('one.xml')/a/b/d" You seem to have fixed this for the sort key (by
using substring-after), but not for the grouping key.

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


> -----Original Message-----
> From: Angela Williams [mailto:Angela.Williams@xxxxxxxxxxxxxxxxxx] 
> Sent: 06 March 2007 22:33
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] for-each-group usage
> 
> Hello!
> 
> I have a mistake in my XSLT 2.0 stylesheet below that is 
> causing the grouping mechanism to not work properly. I've 
> used for-each-group successfully in the past, but this is 
> more complicated (or I am just making it more so). 
> 
> Will someone please point out my error?
> Also, is there a more elegant/efficient way of going about this?
> 
> I have two xml files. One.xml contains my data objects and 
> two.xml defines a list of table columns and tells me which 
> data to put in which column. I need to match on my table 
> columns and inject the data at run time.
> 
> Desired output:
> Seed Pod
> Apple		E 
> Orange	E
> 
> Root
> Potato	E
> Carrot	E
> 
> Actual output:
> Seed Pod
> Apple		E
> Potato	E
> Orange	E
> Carrot	E
> 
> Root
> Apple		E
> Potato	E
> Orange	E
> Carrot	E
> 
> One.xml:
> <a>
>   <b>
>     <c>Apple</c>
>     <d>Seed Pod</d>
>     <e> E </e>
>   </b>
>   <b>
>     <c>Potato</c>
>     <d>Root</d>
>     <e> E </e>
>   </b>
>   <b>
>     <c>Orange</c>
>     <d>Seed Pod</d>
>     <e> E </e>
>   </b>
>   <b>
>     <c>Carrot</c>
>     <d>Root</d>
>     <e> E </e>
>   </b>
> </a>
> 
> Two.xml:
> <table>
>   <data-set>  
>     <row-set xpath="doc('one.xml')/a/b"/>
>     <group-by xpath="doc('one.xml')/a/b/d"/>
>     <order-by xpath="doc('one.xml')/a/b/c"/>
>   </data-set>
>   <columns>
>     <column>
>       <data-value xpath="doc('one.xml')/a/b/c"/>
>     </column>
>     <column>
>       <data-value xpath="doc('one.xml')/a/b/e"/>
>     </column>
>   </columns>
> </table>
> 
> And my stylesheet (included in a master file - I can send that if
> needed.):
> <xsl:stylesheet xmlns:fo="http://www.w3.org/1999/XSL/Format"; 
>   xmlns:xs="http://www.w3.org/2001/XMLSchema"; 
>   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; 
>   xmlns:sax="http://saxon.sf.net/"; version="2.0">
> 
>   <xsl:template match="columns">
>     <xsl:variable name="cols" select="." />
> 
>     <xsl:variable name="rows" as="xs:string">
>       <xsl:value-of select="../data-set/row-set/@xpath" />
>     </xsl:variable>
> 
>     <xsl:variable name="group" as="xs:string">
>       <xsl:value-of select="../data-set/group-by/@xpath" />
>     </xsl:variable>
> 
>     <xsl:variable name="sort" as="xs:string">
>       <xsl:value-of select="../data-set/order-by/@xpath" />
>     </xsl:variable>
> 
>     <xsl:for-each-group select="sax:evaluate($rows)" 
>                         group-by="sax:evaluate($group)">
>       <xsl:sort select="sax:evaluate(
>                           substring-after($sort, concat($rows, '/'))
>                         )" />
>       <fo:table-row>
>         <fo:table-cell>
>           <fo:block>
>             <xsl:value-of select="current-grouping-key()" />
>           </fo:block>
>         </fo:table-cell>
>       </fo:table-row>
>       <xsl:for-each select="current-group()">
>         <xsl:variable name="node" select="." />
>         <fo:table-row>
>           <xsl:for-each select="$cols/column">
>             <fo:table-cell column-number="{position()}">
>               <fo:block>
>                 <xsl:variable name="field">
>                   <xsl:value-of select="data-value/@xpath" />
>                 </xsl:variable>
>                 
>                 <xsl:value-of 
>                    select="$node/sax:evaluate(
>                              substring-after($field, 
> concat($rows, '/'))
>                           )" />
>               </fo:block>
>             </fo:table-cell>
>           </xsl:for-each>
>         </fo:table-row>
>       </xsl:for-each>
>     </xsl:for-each-group>
>   </xsl:template>
> </xsl:stylesheet>
> 
> Thanks!
> Angela Williams
> Angela.Williams@xxxxxxxxxxxxxxxxxx
> Austin, TX

Current Thread