Reputation: 3528
I'm currently trying to upgrade from XSLT 1.0 to XSLT 2.0. I had the following in one of my templates that used to work with XSLT 1.0 :-
<xsl:template name="some_t">
<xsl:param name="some_numeric_param"/>
<xsl:if test="$some_numeric_param != ''">
<xsl:attribute name="some_name">
<xsl:value-of select="$some_numeric_param"/>
</xsl:attribute>
</xsl:if>
</xsl:template>
Now, there are three cases in which I call this template :-
<xsl:call-template name="some_t">
<xsl:with-param name="some_numeric_param" select="floor(number(./@attr1) div 20)"/>
</xsl:call-template>
When I do this, basically the inner template will only create the attribute called "some_name" iff the attribute called "attr1" is given in the source document.
Also, another situation in which I might call this is without this param :-
<xsl:call-template name="some_t">
</xsl:call-template>
So What I basically want it to do is that when I pass in a parameter then create an attribute, otherwise don't. Whether my stylesheet is correct or not, this worked in XSLT 1.0 but in XSLT 2.0 it gives an error that says :-
Error on line 195 of movwin.xsl:
XPTY0004: Cannot compare xs:double to xs:string
Transformation failed: Run-time errors were reported
Any help? I'm using the Saxon 9.4 processor.
Upvotes: 2
Views: 4526
Reputation: 163262
It's a good idea in 2.0 to declare the types of your parameters. If you're expecting an integer, declare <xsl:param name="p" as="xs:integer"/>
- and don't try comparing it to a string. If the integer might or might not be present, declare it as an optional integer like this: <xsl:param name="p" as="xs:integer?"/>
and use the empty sequence (written ()
) as a 'null value'. You can then test whether a value has been supplied using test="empty($p)"
.
Your 1.0 code works because when you compare a number to a string, the string is converted to a number. The empty string converts to NaN, and NaN compares not equal to anything. I think -- though I would need to check -- that that still works in 2.0 if you run in backwards compatibility mode, which happens if your styesheet specified version="1.0".
Upvotes: 5
Reputation: 52848
It's because you're comparing a number to a string.
Try changing:
<xsl:if test="$some_numeric_param != ''">
To:
<xsl:if test="$some_numeric_param">
EDIT
To also handle $some_numeric_param = 0
try:
<xsl:if test="string($some_numeric_param)">
There's no need to do the != ''
comparison.
Upvotes: 2
Reputation: 2157
Try coercing the input param into a string:
<xsl:if test="string($some_numeric_param) != ''">
xslt 2.0 is more strongly typed than 1.0.
Upvotes: 1