Java Guy
Java Guy

Reputation: 53

XML Schema Choice - choose at lease one, but no repeat

How can I enforce to chose at lease one, but no repeat?

The following syntax allows any c element to repeat up to 3 times.

<choice minOccurs="1" maxOccurs="3">
    <element name="c1" type="string" />
    <element name="c2" type="string" />             
    <element name="c3" type="string" />
</choice>

thnx

steve

Upvotes: 3

Views: 4716

Answers (1)

Petru Gardea
Petru Gardea

Reputation: 21638

Loose the maxOccurs="3" and what you got is "choose at least one", no repeat.

For particles, the default is minOccurs="1"; a mandatory choice, where each option particle is itself mandatory, is your answer.

UPDATE: Based on your comment, if what you're looking is for any ordered combination of the particles you've described, this is the best you can get with XSD spec.

<?xml version="1.0" encoding="utf-8" ?>
<xsd:schema targetNamespace="http://tempuri.org/XMLSchema.xsd" elementFormDefault="qualified" xmlns="http://tempuri.org/XMLSchema.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:element name="root">
        <xsd:complexType>
            <xsd:choice>
                <xsd:sequence>
                    <xsd:element ref="c1"/>
                    <xsd:element ref="c2" minOccurs="0"/>
                    <xsd:element ref="c3" minOccurs="0"/>
                </xsd:sequence>
                <xsd:sequence>
                    <xsd:element ref="c2"/>
                    <xsd:element ref="c3" minOccurs="0"/>
                </xsd:sequence>
                <xsd:element ref="c3"/>
            </xsd:choice>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name="c1" type="xsd:string"/>
    <xsd:element name="c2" type="xsd:string"/>
    <xsd:element name="c3" type="xsd:string"/>
</xsd:schema>

This is messy already; if you're looking for a greater number of particles or any unordered combination, then I would change the model to something like this (these are XSD 1.0 limitations in action - it all has to do with limitations in the XPath syntax you can use for selectors/fields).

<?xml version="1.0" encoding="utf-8" ?>
<xsd:schema targetNamespace="http://tempuri.org/XMLSchema.xsd" elementFormDefault="qualified" xmlns="http://tempuri.org/XMLSchema.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:element name="root">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element ref="c" maxOccurs="unbounded"/>
            </xsd:sequence>
        </xsd:complexType>
        <xsd:key name="pk">
            <xsd:selector xpath="*"/>
            <xsd:field xpath="@code"/>
        </xsd:key> 
    </xsd:element>
    <xsd:element name="c" type="TC" abstract="true"/>   
    <xsd:element name="c1" type="TC1" substitutionGroup="c"/>
    <xsd:element name="c2" type="TC2" substitutionGroup="c"/>
    <xsd:element name="c3" type="TC3" substitutionGroup="c"/>

    <xsd:complexType name="TC">
        <xsd:simpleContent>
            <xsd:extension base="xsd:string">
                <xsd:attribute name="code" type="xsd:string"/>
            </xsd:extension>
        </xsd:simpleContent>
    </xsd:complexType>
    <xsd:complexType name="TC1">
        <xsd:simpleContent>
            <xsd:restriction base="TC">
                <xsd:attribute name="code" type="xsd:string" fixed="c1"/>
            </xsd:restriction>
        </xsd:simpleContent>
    </xsd:complexType>
    <xsd:complexType name="TC2">
        <xsd:simpleContent>
            <xsd:restriction base="TC">
                <xsd:attribute name="code" type="xsd:string" fixed="c2"/>
            </xsd:restriction>
        </xsd:simpleContent>
    </xsd:complexType>
    <xsd:complexType name="TC3">
        <xsd:simpleContent>
            <xsd:restriction base="TC">
                <xsd:attribute name="code" type="xsd:string" fixed="c3"/>
            </xsd:restriction>
        </xsd:simpleContent>
    </xsd:complexType>  
</xsd:schema>

A sample XML would like this:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- Sample XML generated by QTAssistant (http://www.paschidev.com) -->
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://tempuri.org/XMLSchema.xsd">
    <c1 code="c1">c11</c1>
    <c2 code="c2">c21</c2>
    <c3 code="c3">c21</c3>
</root>

or this:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- Sample XML generated by QTAssistant (http://www.paschidev.com) -->
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://tempuri.org/XMLSchema.xsd">
    <c2 code="c2">c21</c2>
    <c1 code="c1">c11</c1>
</root>

Basically you're keying in on some component that makes your element unique, that is part of the data as opposed to a tag name. Again, messy, but as an exercise, it may give you an idea.

Upvotes: 3

Related Questions