XSD 1.1 assert implementation-dependant result

188 views Asked by At

Consider the following simple Schema with a simple assertion:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" vc:minVersion="1.1">
    <xs:element name="root">
        <xs:complexType>
            <xs:assert test="(8 = 8) or name('error')"></xs:assert>
        </xs:complexType>
    </xs:element>
</xs:schema>

Let's look at the assertion:

(8 = 8) or name('error')

The left operand is true while the second one produces an error if it is evaluated (as name functions expects a node parameter and not a string). Saxon validator says assertion is satisfied, Xerces validator says is not.

According to XPath 1.0 specs

The right operand is not evaluated if the left operand evaluates to true

So according to XPath 1.0 this assertion should be satisfied without raising an error as the right operand should not be evaluated. However, XSD 1.1 uses XPath 2.0, that lets implementation-dependant evaluation order, states:

If XPath 1.0 compatibility mode is false [...] an or-expression can return true if the first expression evaluated is true, and it can raise an error if evaluation of the first expression raises an error [...]. A logical expression is not deterministic in the presence of errors

In XSD 1.1 specs we can clearly read:

For an XPath Expression property record X to be valid, all of the following must be true:

[...]

2.2.1 XPath 1.0 compatibility mode is false.

[...]

So as I understand, in XSD 1.1 XPath compatibilty mode is false, so an assertion result is implementation-dependant, so a XML document shoud be valid against the same XSD depending on validator implementation. In this case Saxon is right stating that assertion is satisfieed and Xerces is also right stating that the assertion is not satisfied. Is that right or am I missing something?

1

There are 1 answers

2
Michael Kay On BEST ANSWER

Yes, you are right. If you want (A or B) where A is guaranteed to be evaluated before B, then you can write test="if (A) then true() else B".