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: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Wed, 19 Feb 2003 10:12:32 +0000
Hi Gunther,

> Thans Jeni for your kind words of support. The problem is 1.0
> backward compatibility doesn't help me (as I do want 2.0, the good
> part of it anyway :-). And as Michael can tell, I have done some
> pushing the envelope of saxon code a bit so that I was hoping a
> recent modification of his would make my life easier. Anyway, I am
> back at v7.3 now and only lost like 3 hours of my life ...

You misunderstand my suggestion about using version="1.0". For
processors that support XSLT 2.0, setting version="1.0" doesn't change
whether or not you can use XSLT 2.0 features (e.g. grouping,
conditional expressions in XPaths), it just changes whether or not
XPath 2.0 is used with the backwards compatibility flag on or off. So
in your words, you get the "good part" of XSLT/XPath 2.0.

The backwards compatibility flag *should* make expressions that are
legal in XPath 1.0 do the same thing in an XPath 2.0 processor as they
do in a XPath 1.0 processor. It should make expressions that are not
legal in XPath 1.0 work roughly in the way that you'd expect them to
were the XPath 1.0 rules extended into XPath 2.0, though as you've
found you can't rely on this.

>> Can you show us the place where you need to use xs:integer? It
>> might be that you can use number() instead?
> See my other messages on this, the particular xs:integer() need came
> from
>   <xsl:template match="display">
>     <xsl:variable name="indent" select="string-pad(' ', @indent)/>
>   </xsl:template>
> where it complains that string-pad wants an xsd:integer as second
> argument.

Hmm... Interestingly in the light of what I said above, this seems to
work if version="2.0" but not if version="1.0".

The signature for string-pad() is:

  string-pad($padString as xs:string, $padCount as xs:integer)
    as xs:string?

It works if version="2.0" because the type of the value of the @indent
attribute is xdt:anyAtomicType, and when you pass a value of type
xdt:anyAtomicType as an argument to a function it just gets converted
automatically to the required type for the argument. So in this case
the xdt:anyAtomicType value from the indent attribute gets converted
to an xs:integer.

On the other hand, if version="1.0" and the backwards compatibility
flags apply then a numeric required type for the argument entails
converting the argument to a xs:double value. As you've found, the
xs:double value then can't be automatically converted to an integer,
which is why you need the explicit cast. This isn't an issue with the
XPath 1.0 functions because they all expect doubles, but as you've
found, several of the new functions only accept integers.

(FWIW, I thought that floor(), ceiling() or round() might help here,
but they all return doubles, I think for compatibility with XPath 1.0,
so that they can return NaN.)

So the fix here, if you want to avoid declaring and using the XML
Schema namespace, actually seems to be to use version="2.0" rather
than version="1.0".



Jeni Tennison

 XSL-List info and archive:

Current Thread