Description
The bug can be demonstrated with the following stylesheet:
<?xml version="1.0"?>
<!-- bug1.xsl -->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:param name="six" select="/input/@six"/>
<xsl:template match="/">
<result>
<xsl:if test="5 < $six">
okay 5 lt $six
</xsl:if>
<xsl:if test="7 < $six">
fail 7 lt $six
</xsl:if>
<xsl:if test="$six > 5">
okay $six gt 5
</xsl:if>
<xsl:if test="$six > 7">
fail $six gt 7
</xsl:if>
</result>
</xsl:template>
</xsl:stylesheet>
Given the input:
<?xml version="1.0"?>
<!-- in1.xml -->
<input six="6"/>
The correct result produced by the Xalan interpreter is:
xalan -in in1.xml -xsl bug1.xsl
<result>
okay 5 lt $six
okay $six gt 5
</result>
XSLTC 2.6.0 produces a wrong result where 7 < $six evaluates as true:
xalan -in in1.xml -xsl bug1.xsl -xsltc -v
>>>>>>> Xalan Version Xalan Java 2.6.0, <<<<<<<
<result>
fail 7 lt $six
okay $six gt 5
</result>
The bug is introduced because for simplifying the comparison the operands are swapped without adapting non-commuting operators accordingly. Here is the patch to be applied in org/apache/xalan/xsltc/runtime/BasisLibrary.java:
— BasisLibrary.java.orig 2004-02-27 20:45:28.000000000 +0100
+++ BasisLibrary.java 2004-12-21 10:48:29.644000000 +0100
@@ -741,8 +741,16 @@
if (hasSimpleType(left) ||
left instanceof DOM && right instanceof DTMAxisIterator)
if (left instanceof DOM) {
This particular bug manifests itself only under very specific circumstances. It only occurs if a node-set is passed as parameter (<xsl:param> or <xsl:with-param>) and used as right-hand-side operator in a relational expression.
If one is aware of it's presence, it can be avoid be any of these variations:
*) Use variable instead of parameter:
<xsl:variable name="six" select="/input/@six"/>
*) Explicit conversion to number in assignment:
<xsl:param name="six" select="number(/input/@six)"/>
*) Explicit conversion to number in expression:
<xsl:if test="7 < number($six)">
*) Move parameter to left-hand-side:
<xsl:if test="$six >= 7">
PS What I didn't understand is the difference between xsl:param and xsl:variable. Why does Param.typeCheck cast _select from node-set to reference?
Attachments
Issue Links
- duplicates
-
XALANJ-2003 XSLTC tail recursion outputs backwards
- Resolved