torsten
torsten

Reputation: 463

XML Schema content model is not deterministic

i have trouble with a xml schema.

First I want to show you the possible cases of xml:

1.

<arrivalDate>01.01.2012</arrivalDate>

2.

<arrivalDate>01.01.2012</arrivalDate>
<departureDate>04.01.2012</departureDate>

3.

<arrivalDate>01.01.2012</arrivalDate>
<presentee>
    <firstName>User</firstName>
</presentee>

4.

<arrivalDate>01.01.2012</arrivalDate>
<departureDate>04.01.2012</departureDate>
<presentee>
    <firstName>User</firstName>
</presentee>

5.

<arrivalDate>later</arrivalDate>
<presentee>
    <firstName>User</firstName>
</presentee>

6.

<arrivalDate>later</arrivalDate>
<departureDate>5</departureDate> <!-- 1 till 5 extra days -->
<presentee>
    <firstName>User</firstName>
</presentee>

The cases 5 and 6 are only possible if presentee is set.

Now I've created a schema for handle this:

<xs:choice>
    <xs:sequence>
        <xs:choice>
            <xs:sequence>
                <xs:element name="arrivalDate" type="date" />
                <xs:element name="departureDate" type="date" minOccurs="0" maxOccurs="1" />
            </xs:sequence>
            <xs:sequence>
                <xs:element name="arrivalDate" type="xs:string" fixed="later" />
                <xs:element name="departureDate" minOccurs="0" maxOccurs="1">
                    <xs:simpleType>
                        <xs:restriction base="xs:integer">
                            <xs:minInclusive value="1" />
                            <xs:maxInclusive value="5" />
                        </xs:restriction>
                    </xs:simpleType>
                </xs:element>
            </xs:sequence>
        </xs:choice>
        <xs:element name="presentee" minOccurs="1" maxOccurs="1">
            <xs:complexType>
                <xs:sequence>
                    <xs:element name="title" type="title"/>
                    <xs:element name="firstName" type="name" />
                    <xs:element name="lastName" type="name" />
                </xs:sequence>
            </xs:complexType>
        </xs:element>
    </xs:sequence>
    <xs:sequence>
        <xs:element name="arrivalDate" type="date" />
        <xs:element name="departureDate" type="date" minOccurs="0" maxOccurs="1" />
    </xs:sequence>
</xs:choice>

I tried several changes to the structure, to handel the problem, but im don't get a "nice" solution.

Upvotes: 3

Views: 8872

Answers (2)

G_H
G_H

Reputation: 12009

The reason your XML schema is non-deterministic, is that when applying it to an XML document it can't decide which of the definitions for arrivalDate and departureDate you mean. You manner of thinking is that the first <choice> directive gives you a choice between either one set of definitions for these elements, followed by a presentee element, or another definition without the presentee element. Unfortunately XML Schema does not perform some look-ahead.

Upon parsing, the XML events are presented to a validator one by one. So the arrivalDate is given to your schema and now it has to know whether the element is valid or not, but... it can't figure out which of these arrival date definitions apply. If it could defer that decision to later when it has parsed subsequent elements it could, like how it might decide an element is invalid by missing certain child elements. But given that they're separate, this isn't possible in this way.

W3C XML Schema is bad at a couple of things: unordered content and cross-node restrictions. Like Kevin suggested, XML Schema 1.1 might have an answer to that. I haven't worked with it. Other options to check are RelaxNG, which is more flexible and powerful than XML Schema, or Schematron, which allows for exactly this sort of validation that needs to go deeper than structure and simple type-checks.

Upvotes: 4

Kevin
Kevin

Reputation: 1978

This is not something XSD 1.0 can handle. XSD models are deterministic and as you are realizing, your language is not deterministic.

You could use union to have a type that could be either a date or some certain string values, but there is nothing in XSD to let you specify that a later element must be present when arrival/departure is not just a date.

I don't know whether XSD 1.1 is an option for you, but it has assertions, which might help you.

Upvotes: 2

Related Questions