RE: Incompatibilities XPath 1.0 vs 2.0?

> I *think* that there are some problems with backwards compatibility
> that aren't listed in Appendix D of the XPath 2.0 WD.
> 
> Section 2.3.3.1 Predicates:
> 
>  "If the value of the predicate expression is one simple value of a
>   numeric type, the value is rounded to an integer using the rules of
>   the round function, and the predicate truth value is true if and
>   only if the resulting integer is equal to the value of the context
>   position."
> 
> I haven't got access to the XPath 1.0 errata at the moment, but at
> least some of the implementations (Saxon and Xalan) seem to round down
> (floor) numeric predicates rather than rounding them (round).

I think you've uncovered a rat's nest here. XPath 1.0, as I read it, doesn't
specify any rounding, it simply tests whether the numeric value of the
predicate is equal to the value of the context position. There's no erratum
affecting this. So $x[1.7] should return an empty node-set. Yes, Saxon 6.5
appears to round down: I think that's a bug. Saxon 7.0 implements the XPath
2.0 spec as written above. 

I don't think we made a deliberate decision to change the rules here for
XPath 2.0, it's something that happened by accident, and I personally think
we should revert to the XPath 1.0 behavior, since I don't think there's a
strong reason to prefer anything different. 
> 
> ---
> 
> Also, I think the definition for predicates changes what happens when
> the predicate expression evaluates to a string. In XPath 1.0, the
> string is converted to a boolean (an empty string to false, a string
> with characters to true), and this is used. For example:
> 
>   text()[normalize-space()]
> 
> returns text nodes whose value contains non-whitespace characters. It
> appears from the description in Section 2.3.3.1 that this expression
> will now raise an error, since it is not an empty sequence, not a
> numeric type, not boolean, and not a sequence of nodes.

You're right: either there's an error in the spec as written, or there is a
backwards incompatibility that we haven't documented. Given the amount of
discussion we had on this, I'm not sure which of these alternatives is true,
but either way, the spec needs fixing. My suspicion is that the last step
should say a type exception is invoked (not an error) - in which case the
behaviour is as for logical expressions, see below.
> 
> ---
> 
> On a similar note, Section 2.7 Logical Expressions doesn't seem to
> handle situations where the expressions are other than nodes or
> boolean values. What about if one of the operands is a string or a
> number? No mention is made of the required types of the comparison or
> how other values are cast to boolean values, which presumably they
> should be.

In this case we're being rather devious. What happens is that a type
exception is invoked (by rule 4). Which means you cut to section 2.1.2 which
explains how type exceptions are handled: specifically, when the host
language chooses, by invoking fallback rules for conversion to a boolean.
The reason for the deviousness is that it allows host languages (perhaps at
user option) to make this an error. 
> 
> ---
> 
> In Appendix A.3, it says:
> 
>  "A space may be significant after "/" or "//", in order to
>   distinguish, for instance "//div" and "// div foo" without 
> lookahead."
> 
> This was not the case in XPath 1.0 (where you could do / div div 3
> quite happily if you felt so inclined). (I don't think there's a
> problem with "//" - that's not a valid path expression anyway.)
> 
Yes, I'm not sure we've got this right. There was actually a buglet in XPath
1.0, namely that "div" after "/" was always interpreted as an element name,
never as an operator. It doesn't really matter: root nodes are not often
needed as the operand of a division. It matters more in XPath 2.0, with the
increasing range of operator keywords, some of which are operators that
might meaningfully be used with "/" as an operand, e.g. "if(/ precedes .)".
The suggestion here is that a space after the "/" should distinguish the two
cases. If this is what we decide, then it is indeed an incompatibility.
Personally, I'd be happier asking users to write "if((/) precedes .)".

[Incidentally, since we go out of our way to mention the need to sometimes
put a space before "-" to stop it being swallowed as part of a name, we
ought to say the same about "."].

Mike Kay

Received on Thursday, 3 January 2002 10:55:25 UTC