Re: [xsl] The Perils of Sudden Type-Safety in XPath 2.0

Subject: Re: [xsl] The Perils of Sudden Type-Safety in XPath 2.0
From: "Charles White" <chuck@xxxxxxxxxxx>
Date: Wed, 19 Feb 2003 10:06:03 -0800
Hi Jeni:

Yes, sorry, I wasn't very clear. I'm hesitant to ask too many questions on
the list about 2.0 because I haven't finished going over the specs, but your
explanation will make reading the spec much more understandable, so thank
you for the detailed explanation.

Just to help clarify, then, if I have an expression in XSLT 2.0 like this:
4.5 + 5.5

it should yield 10.0 in XPath 2.0, right?

This would have yielded 10 in XSLT 1.0.

If I am using an XSLT 2.0 compliant processor, and I want to maintain my
original results, is the solution as you described to Gunther, to keep the
version attribute value at "1.0" and that otherwise XPath 2.0 casting takes
over and therefore the result will be an xs:decimal type? But I'll still
have the benefit of using, for example, xsl:for-each-group?

I think I actually like that type casting seems less arbitrary than before,
although I haven't quite nailed down the particulars yet. As long as there
is some kind of switch, it all seems cool.


~ chuck white

> Hi Chuck,
> > I'm only now starting to play around with XSLT 2.0, so this is a
> > question I am posing to you , not an argument. Can you give me an
> > example where automatic casting takes place? I tried to create one
> > multiplying two values and assumed, based on this thread, it would
> > return an integer, but it didn't happen. Can you clarify the
> > situation for my muddled mind?
> I'm not exactly sure what you're asking for, but here's an example
> that illustrates what happens when you multiply two values under XSLT
> 2.0.
> Say you had the following unvalidated (and hence untyped) XML:
>   <problem risk="3" severity="4">...</problem>
> and you wanted to create a number of exclamation marks equal to the
> value of @risk * @severity. @risk and @severity are both always
> integers, but the XML is untyped so the XSLT processor doesn't know
> this.
> Since neither @risk nor @severity is typed, an XSLT 2.0 processor
> will assume that since you want to multiply them together they must be
> of type xs:double. When you multiply two doubles, the result is a
> value of type xs:double. If you try to use a double as an argument or
> operand to a function or operator that expects an integer (or indeed
> most other types), you will get a type error. For example, if you try
> to do:
>   <xsl:value-of select="string-pad('!', @risk * @severity)" />
> or:
>   <xsl:for-each select="1 to @risk * @severity">!</xsl:for-each>
> then you will get errors because string-pad() expects an integer as
> its second argument and the 'to' operator expects integers for its
> arguments.
> You have to do one of:
>   - add types to your document by validating it against a schema or by
>     creating a temporary tree in which the attributes are assigned types
>   - cast the values to integers explicitly within the code
>   - use a variable to create an untyped node containing the value
>     which will then be automatically cast to the right type
> Explicit casts look like:
>   <xsl:value-of select="string-pad('!', xs:integer(@risk * @severity))" />
> Creating the variable looks like:
>   <xsl:variable name="danger">
>     <xsl:value-of select="@risk * @severity" />
>   </xsl:variable>
>   <xsl:value-of select="string-pad('!', $danger)" />
> This latter works because the $danger variable holds the document node
> of a tree that contains the value of @risk * @severity. The typed
> value of the document node is the value 7 of the type
> xdt:untypedAtomic [*]. Since the type is xdt:untypedAtomic, the value
> is cast automatically to the required type of xs:integer when the
> variable is used.
> Cheers,
> Jeni
> [*] I mistakenly talked about the type xdt:anyAtomicType in an earlier
> mail when I meant xdt:untypedAtomic.
> ---
> Jeni Tennison
>  XSL-List info and archive:

 XSL-List info and archive:

Current Thread