Reputation: 53
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
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