Re: [xsl] Subject: Counting Path Occurrences

Subject: Re: [xsl] Subject: Counting Path Occurrences
From: "Scott Coon" <scoon@xxxxxxxxxxxxx>
Date: Tue, 3 Apr 2007 19:21:14 -0700
Michael Kay wrote:
> Scott Coon wrote:
> > So, start with a stylesheet function to generate the paths
> > (/a/b/x) using the ancestor-or-self axis:
> >
> > <xsl:function name="gn:path">
> > 	<xsl:param name="node" as="node()"/>
> > 	<xsl:for-each select="$node">
> > 		<xsl:for-each select="ancestor-or-self::*"><xsl:value-of
> > select="concat('/', name())"/></xsl:for-each>
> > 	</xsl:for-each>
> > </xsl:function>
>
> Actually that function generates a sequence of text nodes.

That was the original source of my confusion.  :)  Is that because of
the "for-each" over the ancestor-or-self axis?

> >
> > My hope was to use it like this in the template that matches "/":
> >
> > <xsl:for-each-group select="descendant-or-self::*"
> > group-by="gn:path(.)">
> > 	Path: <xsl:value-of select="gn:path(.)"/> - Count:
> > <xsl:value-of select="count(current-group())"/>
</xsl:for-each-group>
> >
> > Unfortunately, stylesheet functions only return item()*, not
> > string,
>
> Stylesheet functions return whatever you choose them to return. The
simplest
> way to return the string you want is
>
> <xsl:function name="gn:path" as="xs:string">
>   <xsl:param name="node" as="node()"/>
>   <xsl:sequence select="concat('/',
string-join(ancestor-or-self::*/name(),
> '/'))"/>
> </xsl:function>
>

I want to make sure I understand this:  is the "xsl:sequence" operation
constructing a sequence that contains the results of the "select"
attribute?  And does that result in a single text node because of the
concat?  And is that enforced at runtime by the "as" attribute in your
function declaration?

Thanks,
Scott

Current Thread