XML Schema 1.1 assertions: How to catch a dynamic type error?

418 views Asked by At

I'm currently struggling with assertions in XML Schema 1.1. The XML Schema 1.1 recommendation states that an assertion is violated if an error occurs during its execution. This behavior seems reasonable, but might cause some confusion when trying to understand evaluation results. Let me explain:

The following example XSD explains defines two elements: str and dec. The element str must have the value "A" or "B". The element dec must be a number. In addition, dec must be positive if str has the value "A". I tried to define this last property by using an assertion:

<?xml version="1.0" encoding="utf-8"?>

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="data">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="str">
          <xs:simpleType>
            <xs:restriction base="xs:string">
              <xs:enumeration value="A"/>
              <xs:enumeration value="B"/>
            </xs:restriction>
          </xs:simpleType>
        </xs:element>
        <xs:element name="dec" type="xs:decimal"/>
      </xs:sequence>
      <xs:assert test="str != 'A' or dec gt 0"/>
    </xs:complexType>
  </xs:element>
</xs:schema>

The following XML file is invalid because the element str has the value "X", which is not allowed.

<?xml version="1.0" encoding="utf-8" ?>
<data>
  <str>X</str>
  <dec>5</dec>
</data>

When I now validate the XML file using Saxon 9.6.0.6 I get the following output:

Validation error on line 3 column 16 of test.xml:
  XSD: The content "X" of element <str> does not match the required simple type. Value "X"
  contravenes the enumeration facet "A, B" of the type of element str
  Validating /data[1]/str[1]
  See http://www.w3.org/TR/xmlschema11-2/#cvc-datatype-valid clause 1
Warning: on line 1 
  Internal error: value doesn't match its type annotation. Value "X" contravenes the
  enumeration facet "A, B" of the type of element str
Validation error at data on line 5 column 8 of test.xml:
  XSD: Element data does not satisfy assertion str != 'A' or dec gt 0
  Validating /data[1]

As you can see, I get two errors reported for just one problem (illegal value of element str). I find this behavior quite confusing since it makes it harder to see the real problem (wrong value, instead of failed assertion).

Is there any way to "catch" the type error in the assertion so that the assertion does not fail in this example?

1

There are 1 answers

1
Michael Kay On BEST ANSWER

Interesting. Saxon, like most validators, will try to be helpful by catching as many validation errors as it can in a single run. But this is only useful if the errors are independent of each other. Testing assertions on values that are known to be invalid isn't very helpful: but of course, the assertion is executed "blindly" by an XPath processor that doesn't know about what errors have already been reported.

The fact that Saxon reports an "internal error" here is a clue that it's not supposed to work this way. I'll log a bug on this and see what we can do.

Assertions are rather strange in that they operate on data that has been half-validated: this makes for rather complicated rules about whether they are operating on typed or untyped values. In the circumstances, I doubt that coding your assertions more defensively is likely to help matters much. But it might make sense to code 'dec must be positive if str has the value "A"' more directly as "if (str='A') then dec>0 else true()".