Re: [xsl] XSLT 2.0 Multi-level grouping

Subject: Re: [xsl] XSLT 2.0 Multi-level grouping
From: Abel Braaksma <abel.online@xxxxxxxxx>
Date: Fri, 11 Jan 2008 01:56:56 +0100
Florent Georges wrote:
Michael Kay wrote:
<xsl:for-each-group select="*" group-by="name()">

I know name() is widely used as a grouping key, but I wonder if we shouldn't use node-name(.) instead, to be more coherent regarding namespaces handling. The same way we advice to use self::ns:name instead of name() eq 'ns:name'.

apart from some special characteristics (i.e., empty string vs an empty sequence and some others), name() is defined as string(node-name($arg)). I agree with your point that using it node-name() instead of name() would be more "correct", but knowing that many people come from XSLT 1.0 where they are used to using name(), I don't really see the difference (even though one might argue that a string is compared differently than a QName).


One special situation occur, perhaps, where the source document has different redefining namespaces with the same prefix (or different null namespaces). In that case and in the rare event that the node names match, the node-name() function will result in unequal and the name() function will result in equal:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; version="2.0">


<xsl:output method="text" />
<xsl:variable name="testset">
<date xmlns="http://foo"; />
<date xmlns="http://bar"; />
</xsl:variable>
<xsl:template match="/" name="start">
<xsl:value-of select="
'node-name comparison:', node-name($testset/*[1]) eq node-name($testset/*[2])" />
<xsl:text>&#xA;</xsl:text>
<xsl:value-of select="
'name comparison:', name($testset/*[1]) eq name($testset/*[2])" />
</xsl:template>
</xsl:stylesheet>


Will output the following:

node-name comparison: false
name comparison: true



So, all in all and in the end, to prevent hard to find errors, I tend to agree with your advice and adopt it as a "best practice".

Cheers,
-- Abel Braaksma

Current Thread