RE: [xsl] Return value from a template 2...

Subject: RE: [xsl] Return value from a template 2...
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Wed, 23 Jan 2008 09:14:53 -0000
>        <xsl:template match="/root">
>                <xsl:variable name="idList">
>                        <xsl:call-template select="/root/vid" 
> name="getIdList" />
>                </xsl:variable>
>                <xsl:value-of select="$idList"/>
>        </xsl:template>

I'm amazed when you say you "get nothing". What processor are you using? You
should get a string of compiler error messages. The first one should say
that xsl:call-template cannot have a select attribute. If you want to pass a
parameter with call-template, use xsl:with-param.
> 
>        <xsl:template match="/root/vid" name="getIdList">

It's not actually an error to have both a "match" and a "name" on a
template: it means you can invoke it using either call-template or
apply-templates. But it can be a bit misleading - when invoked using
apply-templates, the name is ignored, and when invoked using call-template,
the match is ignored.

>                <xsl:for-each select=".">

I don't know what you thought xsl:for-each select="." would do, but it's a
no-op. It iterates over the node-set that contains a single node, the
context node, and makes each node in that node-set the context node in turn.
In other words, it does nothing.

>                        <xsl:variable name="var"
> select="concat($var,ids, $delimiter)"/>

This is where you should get your second error. The variable $var referenced
in the select expression has not been declared. You can't refer to a
variable within its own declaration.

>                </xsl:for-each>
>                <xsl:value-of select="$var"/>

And here is your third syntax error; the variable $var that you declared
earlier went out of scope when the for-each ended. (When I said the for-each
had no effect, I lied. It has the effect of making your variable
inaccessible.)

>        </xsl:template>
> 
> </xsl:stylesheet>
> 
> What's wrong in it? is there another simple way to get what i want?
> 

You haven't shown your input structure so I'm reduced to guessing.

With XSLT 2.0, I would think the answer is:

<xsl:template match="/">
  <xsl:variable name="idList" select="string-join(/root/vid/id, ',')"/>
  ...

With 1.0, that becomes

<xsl:variable name="idList">
   <xsl:for-each select="/root/vid/id">
     <xsl:value-of select="."/>
     <xsl:if test="position()!=last()">,</xsl:if>
   </xsl:for-each>
</xsl:variable>

You can add a call-template if you want, but it doesn't add much value.

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

Current Thread