How can I combine a restriction with occurence indicators in an XSD file?

471 Views Asked by At

Suppose I have the following XSD file :

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified"  elementFormDefault="qualified" version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="PACIDemoSignedDoc" type="PACIDemoSignedDocType" />
    <xs:complexType name="PACIDemoSignedDocType">
        <xs:all>
            <xs:element name="OwnerEnglishName" type="OwnerEnglishNameType" />
        </xs:all>
    </xs:complexType>
    <xs:complexType name="OwnerEnglishNameType">
        <xs:simpleContent>
            <xs:restriction base="NameType">
                <xs:enumeration value="John"/>
                <xs:enumeration value="Jack"/>
            </xs:restriction>
        </xs:simpleContent>
    </xs:complexType>
    <xs:complexType name="NameType">
        <xs:simpleContent>
            <xs:extension base="xs:string"/>
        </xs:simpleContent>
    </xs:complexType>
</xs:schema>

My question is, where should I add the attributes minOccurs and maxOccurs for the element "OwnerEnglishName" ? I want to keep xs:all as I want to avoid having to order my XML file in sequence but it prohibits me from adding the Occurs directly in the <xs:element name="OwnerEnglishName" type="OwnerEnglishNameType" /> line...

I'm also guessing I can't add the Occur attributes inside OwnerEnglishNameType, anyone have any idea ?

2

There are 2 best solutions below

1
Yohann On BEST ANSWER

Okay, I have solved my problem, here's the answer if others have the same problem :

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" targetNamespace="test" xmlns="test" elementFormDefault="qualified" version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="animal" type="AnimalType" />
    <xs:complexType name="AnimalType">
        <xs:all>
            <xs:element name="cats" type="Cats" />
        </xs:all>
    </xs:complexType>    
    <xs:simpleType name="CatType">
        <xs:restriction base="xs:string">
            <xs:enumeration value="John"/>
            <xs:enumeration value="Jack"/>
        </xs:restriction>
    </xs:simpleType>    
    <xs:complexType name="Cats">
        <xs:sequence>
            <xs:element maxOccurs="5" minOccurs="2" name="cat" type="Cat"/>
        </xs:sequence>
    </xs:complexType>    
    <xs:complexType name="Cat">
        <xs:simpleContent>
            <xs:extension base="CatType"/>
        </xs:simpleContent>
    </xs:complexType>    
</xs:schema>

which validates the following xml :

<?xml version="1.0" encoding="UTF-8"?>
<animal xmlns="d" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="test schema.xsd">
    <cats>
        <cat>John</cat>
        <cat>Jack</cat>
    </cats>
</animal>

I have successfully bypassed the Occurs restriction of xs:all by adding child elements following xs:sequence.

2
kjhughes On

My question is, where should I add the attributes minOccurs and maxOccurs for the element OwnerEnglishName ?

On the (non-global) declaration of OwnerEnglishName:

<xs:element name="OwnerEnglishName" type="OwnerEnglishNameType" 
            minOccurs="0" maxOccurs="1"/>

I want to keep xs:all as I want to avoid having to order my XML file in > sequence

In XSD 1.0, you cannot have maxOccurs="unbounded" under xs:all; in XSD 1.1, you can.

However, you don't need xs:all with a single child element; you can use xs:sequence since there's no second element for order to matter.


Update (per OP change of example in comments to include additional child elements to xs:all):

You then have three options:

  1. Impose an ordering. This is nearly always the best answer as the perceived need to allow any ordering is almost always unnecessary in practice.
  2. Use XSD 1.1, which allows children of xsd:all to have maxOccurs="unbounded".
  3. Change the XML design to use a wrapper element around the child element of xsd:all which you wish to allow to repeat. (See here for an example.)