[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] Re: XPath 2.0: Problems with the two boolean constants true and false

Subject: Re: [xsl] Re: XPath 2.0: Problems with the two boolean constants true and false
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Thu, 9 Oct 2003 10:34:37 +0100

Hi Dimitre,

> Then, this template:
>   <xsl:template name="And" match="test:*">
>     <xsl:param name="arg1" as="xs:boolean"/>
>     <xsl:param name="arg2"  as="xs:boolean"/>
>          <xsl:value-of 
>          select="$arg1 and $arg2"/>
>   </xsl:template>
> when instantiated with:
>    <xsl:apply-templates select="document('')/*/test:*[1]">
>      <xsl:with-param name="arg1" select="'false'"/>
>      <xsl:with-param name="arg2" select="'true'"/>
>    </xsl:apply-templates>
> will raise an error, because the arguments are strings, but the
> parameters of the template are of type xs:boolean.

Right. Now that we have strong typing, the type of the value that you
pass to a parameter has to be the same as (or implicitly castable to)
the type that you declare for the parameter. You are passing strings
to parameters that are declared as being of type xs:boolean, so you
get a type error.

> Therefore, I am forced to remove the types for the parameters of the
> template and do the conversion myself:
>   <xsl:template name="And" match="test:*">
>     <xsl:param name="arg1"/>
>     <xsl:param name="arg2"/>
>     <xsl:value-of 
>          select="xs:boolean(xs:boolean($arg1) and xs:boolean($arg2))"/>
>   </xsl:template>

Well, only if that's how you choose to solve the problem. In most
scenarios, users should pass values that are of the correct type, in
this case xs:boolean, as in:

   <xsl:apply-templates select="document('')/*/test:*[1]">
     <xsl:with-param name="arg1" select="false()"/>
     <xsl:with-param name="arg2" select="true()"/>

or, if you prefer:

   <xsl:apply-templates select="document('')/*/test:*[1]">
     <xsl:with-param name="arg1" select="xs:boolean('false')"/>
     <xsl:with-param name="arg2" select="xs:boolean('true')"/>

This doesn't solve your problem because you don't know the types of
the required parameters statically. There is another way, though --
you can pass values that are implicitly castable to xs:boolean, as in:

   <xsl:apply-templates select="document('')/*/test:*[1]">
     <xsl:with-param name="arg1">false</xsl:with-param>
     <xsl:with-param name="arg2">true</xsl:with-param>

or even:

   <xsl:apply-templates select="document('')/*/test:*[1]">
     <xsl:with-param name="arg1">
       <xsl:value-of select="'false'" />
     <xsl:with-param name="arg2">
       <xsl:value-of select="'true'" />

These work because the parameters are set to the document nodes of
temporary trees, the typed value of the document node is of type
xdt:untypedAtomic, and xdt:untypedAtomic values can be cast to the
required type implicitly, using the normal casting rules (i.e. the
xs:boolean() function).

In other words, if you want to get implicit casting to a required
type, you should go via xdt:untypedAtomic values (which are most
easily accessible as the typed values of document nodes or text nodes)
rather than xs:string values.



Jeni Tennison

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list

Current Thread