owagh
owagh

Reputation: 3528

How do I test if a parameter has been passed into a template in XSLT v 2.0?

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

Answers (3)

Michael Kay
Michael Kay

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

Daniel Haley
Daniel Haley

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

Steven D. Majewski
Steven D. Majewski

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

Related Questions