tags:

views:

301

answers:

1

I've got a choose statement that should be setting my variable but for some reason the code, though it works elsewhere, does not work in this instance.

Here's my XSLT:

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

<xsl:param name="url-show"/>
<xsl:param name="url-min"/>
<xsl:param name="url-max"/>

<xsl:template match="data">

<xsl:variable name="show" select="$url-show"/>
<xsl:choose>
    <!-- With Min/Max -->
    <xsl:when test="$url-min != '' and $url-max != ''">
     <xsl:variable name="total" select="timeshare-search-results/pagination/@total-entries"/>
    </xsl:when>
    <!-- Without Min/Max -->
    <xsl:otherwise>
     <xsl:variable name="total" select="timeshare-listings/pagination/@total-entries"/>
    </xsl:otherwise>
</xsl:choose>
<xsl:variable name="default" select="$increment"/>
<xsl:choose>
    <!-- With Show Variable -->
    <xsl:when test="$show != ''">
     <xsl:if test="$show &lt; $total or $show = $total">
      <!-- stuff -->
     </xsl:if>
    </xsl:when>
    <!-- Without Show Variable -->
    <xsl:otherwise>
     <xsl:if test="$default &lt; $total or $default = $total">
      <!-- stuff -->
     </xsl:if>
    </xsl:otherwise>
</xsl:choose>

</xsl:template>

</xsl:stylesheet>

I trimmed out the non-essential bits. The funny thing is that when I just have one variable or the other they work just fine. The problem is, they do not show the same data thus I need to choose one or the other based on two URL parameters.

Thing is, I do this elsewhere on this very same page—though I trimmed it out for the example—and it works perfectly fine!

Why isn't it working in this instance? Is there a way I can get around it?

+4  A: 

Variables are immutable in XSLT, and they are scoped and visible from the point of instantiation forward to the end of their parent element.

<xsl:when ...>
    <xsl:variable ...>
</xsl:when>

scopes the variable to just the <xsl:when> block. If there is a variable with that name defined before the <xsl:choose> block, it will appear to be 'restored' when the block is past, since it is no longer shadowed.

The proper way to set a variable is to wrap the <xsl:variable> definition around the <xsl:choose> block, like this:

<xsl:variable name="total">
    <xsl:choose>
        <!-- With Min/Max -->
        <xsl:when test="$url-min != '' and $url-max != ''">
            <xsl:value-of select="timeshare-search-results/pagination/@total-entries"/>
        </xsl:when>
        <!-- Without Min/Max -->
        <xsl:otherwise>
            <xsl:value-of select="timeshare-listings/pagination/@total-entries"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:variable>

Now, $total will be scoped to the parent of the <xsl:variable> block, which is the <xsl:template match="data"> block.

lavinio