4

I need to write an XSD schema. In this schema, some elements are known and mandatory, others are unknown and optional:

<father>
    <childMandatory1 />
    <childMandatory2 />
    <childOptionnal1 />
</father>

or: (changing the mandatory children order)

<father>
    <childMandatory2 />
    <childMandatory1 />
</father>

I know the mandatory children (but not their order). But I don't know if there will be any optional child(ren) (and if so, their names).

I tried with "xs:all", but "xs:all" does not allow "any" :

<xs:element name="father">
        <xs:complexType>
            <xs:all>
                <xs:element ref="childMandatory1" />
                <xs:element ref="childMandatory2" />
                <xs:any minOccurs="0" maxOccurs="unbounded" processContents="lax"/> 
        <!-- error here ! -->
                </xs:all>
            </xs:complexType>
    </xs:element>

I tried with sequence, but I should know the order of elements. (and I don't)

I tried with choice, but choice cannot work with any and some mandatory elements. (and I want to be sure that the mandatory element are present)

Igor Ševo
  • 5,459
  • 3
  • 35
  • 80
GaspardP
  • 880
  • 1
  • 12
  • 24

1 Answers1

1

With your requirement, you have hit the Unique Particle Attribution rule, which is important enough that it has its own Wikipedia page.

The problem is with combining any order with any element anywhere. There is no way that a processor can deterministically determine to what declaration a certain element belongs to. Does childMandatory1 belong to xs:any or does it belong to the element declaration?

As soon as you use xs:any you can easily run into this issue. That is why a sequence is allowed to be combined with xs:any, but only if the items in the sequence are mandatory and in order, otherwise there is again no telling what element belongs to what declaration.

If the reason you create such an XSD is to validate input for the presence of certain elements, you can switch to XSD 1.1, where you can resolve this using xs:assert, or you can use a different tool, like RelaxNg or Schematron, which are alternative standardized XML schema languages.

If you want to create an object model out of this, you may run out of luck, because even if you manage to do so, the (de)serializer will have no way telling the declarations from each other.

Here's an example in XSD 1.1:

<xs:complexType name="BookType">
    <xs:all>
        <xs:any maxOccurs="unbounded" namespace="##any" />
    </xs:all>
    <xs:assert test="self::author | self::title | self:isbn" xpathDefaultNamespace="urn:test" />
</xs:complexType>

A good and helpful article on writing extensible XSD Schema's using Variable Content Containers can be found on XFront. While old, it still very much applies today. There's also an article on the use of xs:any.

Abel
  • 56,041
  • 24
  • 146
  • 247
  • Well, I didn't think like that for the any, but it make sense ! Thanks for the information about UPA. I need a schema in order to validate the xml, but mainly in order to acces the mandatory element (using jaxb objects). I can try to use xsd 1.1 to validate the xml, then use xPath (instead of jaxb objects) to read and use the data. – GaspardP Sep 25 '15 at 07:55