Re: [xsl] Second of two consecutive call-template instructions appears to affect the first?

Subject: Re: [xsl] Second of two consecutive call-template instructions appears to affect the first?
From: Wendell Piez <wapiez@xxxxxxxxxxxxxxxx>
Date: Tue, 14 Mar 2006 12:31:41 -0500
Sebastian,

It appears that while your variables are in scope in the calling template, they are no longer in scope in the templates called.

The solution is to declare them also in the called templates if the execution context (such as the context node) provides access to the values you need for them, or if not (and sometimes even if so), to pass their values into the named templates as parameters.

In XSLT, variables are scoped within the context of their parent elements. As the language is defined in such a way to be "side-effect free", you can't declare a variable in one template and then refer to it in another.

Cheers,
Wendell

At 12:38 PM 3/14/2006, you wrote:
Hi all,

This is a section of a stylesheet I'm working on to convert a simple
custom markup to XHTML.  The section essentially deals with a line
such as:

<photo name="beach" ppos="right" cpos"below" caption="Wish you weren't here!" />

where 'ppos' indicates the position of the photo on the page, and
'cpos' indicates the presence of a caption as well as its position.
Details of the images themselves are included much lower down in the
XML source like so:

  <images>
  .
    <image name="beach">
      <desc>Sunny day on beach</desc>
      <width>300</width>
      <file>images/beach.jpeg</file>
      <flickr>http://static.flickr.com....</flickr>
    </image>
  .
  </images>

If a 'cpos' attribute is specified, but no 'caption' attribute, then
the caption is the description found in <desc> element.  Captions are
optional and not all of the images have flickr addresses.

Basically, my problem is this.  If I comment out the four lines I've
marked with an asterix, the stylesheet processes the source without
any problems whatsoever (and does exactly what I want).  With these
four lines present however, I get the following error at the point
indicated.

"The variable 'name' is not defined"

This seems very strange to me, and needless to say I can't figure out
why it is.  I am simply trying to wrap an <img> element in an anchor
if the image has a flickr address and then write the caption below the
image (in the containing <div>).

Any help much, much appreciated, as always.

sdt.

* All the variables are defined by this point in the stylesheet *

<xsl:choose>
<xsl:when test="$cpos!=''"><!-- there's a caption which requires a surrounding div -->
<div class="{$class}" style="{concat('width:',/page/images/image[@name=$name]/width,'px')}">
<xsl:call-template name="does-image-flickr" />
* <xsl:call-template name="write-caption">
* <xsl:with-param name="cpos"><xsl:value-of select="$cpos" /></xsl:with-param>
* <xsl:with-param name="caption"><xsl:value-of select="$caption" /></xsl:with-param>
* </xsl:call-template>
</div></xsl:when>
<xsl:otherwise><!-- or there isn't -->
<xsl:call-template name="does-image-flickr" />
</xsl:otherwise>
</xsl:choose>


<xsl:template name="does-image-flickr">
<xsl:choose><!-- photo is a flickr link -->
<xsl:when test="/page/images/image[@name=$name]/flickr"> <-- "The variable 'name' is not defined"
<a href="{/page/images/image[@name=$name]/flickr}">
<xsl:call-template name="pass-image-params" />
</a></xsl:when>
<xsl:otherwise><!-- or it isn't-->
<xsl:call-template name="pass-image-params" /></xsl:otherwise>
</xsl:choose>
</xsl:template>


<xsl:template name="pass-image-params">
<xsl:apply-templates select="/page/images/image[@name=$name]">
<xsl:with-param name="cpos"><xsl:value-of select="$cpos" /></xsl:with-param>
<xsl:with-param name="caption"><xsl:value-of select="$caption" /></xsl:with-param>
<xsl:with-param name="class"><xsl:value-of select="$class" /></xsl:with-param>
</xsl:apply-templates>
</xsl:template>


<!-- images -->
<xsl:template match="//image">
<xsl:param name="cpos" />
<xsl:param name="caption" />
<xsl:param name="class" />
<xsl:element name="img">
<xsl:attribute name="alt"><xsl:choose><!-- alt attribute defaults to desc -->
<xsl:when test="$caption!=''"><xsl:value-of select="$caption" /></xsl:when>
<xsl:otherwise><xsl:value-of select="desc" /></xsl:otherwise>
</xsl:choose></xsl:attribute>
<!-- src attribute -->
<xsl:attribute name="src"><xsl:value-of select="file" /></xsl:attribute>
<!-- class attribute required if no caption and hence no containing div -->
<xsl:if test="$cpos=''">
<xsl:attribute name="class"><xsl:value-of select="$class" /></xsl:attribute>
</xsl:if>
</xsl:element>
</xsl:template>


<xsl:template name="write-caption">
<xsl:param name="cpos" />
<xsl:param name="caption" />
<xsl:if test="$cpos='below'"><br /></xsl:if>
<xsl:if test="$cpos!=''"><!-- caption-position specified -->
<xsl:choose><!-- but no caption specified, use desc as default -->
<xsl:when test="$caption!=''"><xsl:value-of select="$caption" /></xsl:when>
<xsl:otherwise><xsl:value-of select="desc" /></xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>




======================================================================
Wendell Piez                            mailto:wapiez@xxxxxxxxxxxxxxxx
Mulberry Technologies, Inc.                http://www.mulberrytech.com
17 West Jefferson Street                    Direct Phone: 301/315-9635
Suite 207                                          Phone: 301/315-9631
Rockville, MD  20850                                 Fax: 301/315-8285
----------------------------------------------------------------------
  Mulberry Technologies: A Consultancy Specializing in SGML and XML
======================================================================

Current Thread