When I try to use the code below I get a duplicate variable error because variables are immutable. How do I set the smaller of the two variables ($nextSubPartPos,$nextQuestionStemPos) as my new variable ($nextQuestionPos)?
<xsl:variable name="nextQuestionPos"/>
<xsl:choose>
<xsl:when test="$nextSubPartPos < $nextQuestionStemPos">
<xsl:variable name="nextQuestionPos" select="$nextSubPartPos"/>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="nextQuestionPos" select="$nextSubPartPos"/>
</xsl:otherwise>
</xsl:choose>
-
Variables in XSLT are immutable. This has tripped me up so many times.
joe : Is there any way to get the larger of the two?phihag : @joe, yes. Replace min with max in my answer or < and > in the questionDimitre Novatchev : Yes, but that's a new question. :) See my answer, it provides more compact and ellegant XPath 1.0 solution and two different XPath 2.0 solutions. -
Don't close the xsl:variable node in the first line. That is, take the / out of it, then put an
</xsl:variable>after</xsl:choose>. Next, change the<xsl:variable>nodes inside the choose to<xsl:value-of>nodes.That is, you want to set the value of the variable with the choose. There are two ways to set the value of a variable. One is the select attribute, the other is the inner text of the node.
<xsl:variable name="nextQuestionPos"> <xsl:choose> <xsl:when test="$nextSubPartPos < $nextQuestionStemPos"> <xsl:value-of select="$nextSubPartPos"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="$nextSubPartPos"/> </xsl:otherwise> </xsl:choose> </xsl:variable> -
Just use the
minfunction:<xsl:variable name="a" select="42" /> <xsl:variable name="b" select="23" /> <xsl:variable name="x" select="min(($a,$b))" />In your example, replace the entire code with:
<xsl:variable name="nextQuestionPos" select="min(($nextSubPartPos,$nextQuestionStemPos))" />Saxon implements min in the global namespace. Other processors may require a namespace, the correct one (usually denoted
fn) ishttp://www.w3.org/2005/02/xpath-functions.nsayer : This solves the immediate problem, but doesn't address the larger question of how to implement complex logic - perhaps logic too complex for XPath - to form a variable's value. -
A compact XPath 1.0 expression that evaluates to the smaller value is:
$v1*($v2 >= $v1) + $v2*($v1 > $v2)
where the $v1 and $v2 variables contain the values to be compared.
So, an elegant one-liner XSLT 1.0 solution will look like this:
<xsl:variable name="v3" select="$v1*($v2 >= $v1) +$v2*($v1 > $v2)"/>
It is easier to define a variable as required in XSLT 2.0:
One can use either the following (more readable) one-liner:
if($v2 gt $v1)
then $v1
else $v2Or the more compact:
min(($v1, $v2))
0 comments:
Post a Comment