RE: [xsl] for-each-group usage

Subject: RE: [xsl] for-each-group usage
From: "Angela Williams" <Angela.Williams@xxxxxxxxxxxxxxxxxx>
Date: Wed, 7 Mar 2007 09:19:19 -0600
That was it - thanks!

Is this stylesheet efficient or is there a better way of doing this?

-----Original Message-----
From: Michael Kay [mailto:mike@xxxxxxxxxxxx]
Sent: Tuesday, March 06, 2007 5:47 PM
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject: RE: [xsl] for-each-group usage

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