1

When I run the following code...

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

<xsl:template match="images">
<ul id="tiles">
    <xsl:for-each select="entry">
        <li>
            <xsl:if test="position() mod 4 = 0">
                <xsl:attribute name="class">fourth</xsl:attribute>
            </xsl:if>

            <xsl:choose>
                <xsl:when test="datei/meta/@width &gt; datei/meta/@height">         
                    <xsl:variable name="width">600</xsl:variable>
                    <xsl:variable name="height">450</xsl:variable>                              
                </xsl:when>
                <xsl:when test="datei/meta/@width &lt; datei/meta/@height">                                 
                    <xsl:variable name="width">600</xsl:variable>
                    <xsl:variable name="height">800</xsl:variable>                      
                </xsl:when>
                <xsl:otherwise>
                    <xsl:variable name="width">600</xsl:variable>
                    <xsl:variable name="height">600</xsl:variable>  
                </xsl:otherwise>
            </xsl:choose>   

            <a href="{$root}/image/2/{$width}/{$height}/5{datei/@path}/{datei/filename}" class="fresco" data-fresco-caption="{titel}" data-fresco-group="event">
                <img src="{$root}/image/2/320/320/5{datei/@path}/{datei/filename}"/>
            </a>
        </li>
    </xsl:for-each>
</ul>
</xsl:template>

</xsl:stylesheet>

I get an error:

XSLTProcessor::transformToXml():
Variable 'width' has not been declared.
xmlXPathCompiledEval: evaluation failed
Variable 'height' has not been declared.
xmlXPathCompiledEval: evaluation failed

How is this possible?

Did I declare the variables width and height in a wrong way?

Thanks for any help.

Tintin81
  • 9,821
  • 20
  • 85
  • 178

3 Answers3

2

You can declare the variable height for example like this:

<xsl:variable name="height">
<xsl:choose>
    <xsl:when test="datei/meta/@width &gt; datei/meta/@height">         
         <xsl:value-of select="'450'"/>                           
    </xsl:when>
    <xsl:when test="datei/meta/@width &lt; datei/meta/@height">
         <xsl:value-of select="'800'"/>                         
    </xsl:when>
    <xsl:otherwise>
         <xsl:value-of select="'600'"/>   
    </xsl:otherwise>
 </xsl:choose>
 </xsl:variable>

As the width is always 600, there's no need to declare it as variable, but maybe that only applies to the example you provided and in other cases the width may vary.

A variable that is declared inside e.g. an <xsl:choose> statement is out of scope outside of this. As there are already good explanations provided in similar questions, just as one reference this answer: Variable scope in XSLT

Community
  • 1
  • 1
matthias_h
  • 11,356
  • 9
  • 22
  • 40
2

I sometimes prefer to use template rules for this:

<xsl:variable name="width">
  <xsl:apply-templates select="datei/meta/@width" mode="width"/>
</xsl:variable>

<xsl:template match="@width[. &gt; ../@height]" mode="width">600</xsl:template>
<xsl:template match="@width[. &lt; ../@height]" mode="width">600</xsl:template>
<xsl:template match="@width" mode="width">600</xsl:template>

etc.

Template rules are the most underused part of XSLT.

Michael Kay
  • 156,231
  • 11
  • 92
  • 164
1

This is an issue of the scope of XSLT variables. You've declared the variables outside of the scope where you'd like to use them. Recast your variable declarations so that the xsl:choose statements fall within the declaration, rather than the other way around.

  • OK, thanks. But what exactly might this look like? I am still new to XSL, so I am not exactly sure what you mean. – Tintin81 Oct 26 '14 at 18:28