RE: [xsl] Grouping using distinct-values

Subject: RE: [xsl] Grouping using distinct-values
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Fri, 4 Jul 2008 10:44:20 +0100
> My thinking has been that I'll write a for loop which will 
> identify all the distinct property_section_nm that I have, 
> and pass each of the distinct values in turn to a 
> call-template which can then group across the xml doc, and, 
> in a for loop of it's own, sort and then output the name=value pairs:
> <xsl:for-each 
> select="distinct-values(record/column[@name='property_section_nm'])">
>     <xsl:variable name="name" select="."/>
>     <xsl:value-of select="$name"/>
>     <xsl:text>
>     </xsl:text>
>     <xsl:call-template name="fred">
>         <xsl:with-param name="nm">$name</xsl:with-param>
>     </xsl:call-template>

distinct-values() returns a sequence of atomic values, so within this
for-each, the context item is an atomic value. This context item is passed
to the called template. 
> <xsl:template name="fred">
>     <xsl:param name="nm"/>
>     <xsl:for-each-group
> select="/database/table[@name='tbl_nm']/record[column[@name='p
> roperty_section_nm'
> and .=$nm]]" group-by=".">
>         <xsl:sort select="column[@name='sort_order']" 
> data-type="number"/>
>         <xsl:value-of 
> select="concat(column[@name='property_nm'], '=', 
> column[@name='property_value'])"/>
>         <xsl:text>
>         </xsl:text>
>     </xsl:for-each-group>
> </xsl:template>
> but I'm getting an error message that my context item:
> "/database/table[@name='tbl_nm']/record[column[@name='property
> _section_nm' and .=$nm]]" isn't a node. 

Correct. It's an atomic value. A path expression starting with "/" starts by
selecting the root of the document containing the context node, and if there
is no context node, it won't work. You need to bind a variable to this
document, probably a global variable will do:

<xsl:variable name="root" select="/"/>

and then you can do select="$root/database/table...."

Michael Kay

Current Thread