I have a complex type like:
<xs:complexType name="blocks">
<xs:sequence>
<xs:element name="BlockA" type="blockA" minOccurs="1" maxOccurs="unbounded"/>
<xs:element name="BlockB" type="blockB" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="Name" type="xs:string" use="required" />
<xs:attribute name="Use" type="xs:boolean" use="required" /></xs:complexType>
but it is not configured how I would like.
I want it so that
- Elements 'BlockA' and 'BlockB' can be in ANY order
- BlockA has to occur at least 1 time.
- BlockB can occur 0 or more times.
The XSD order indicators 'sequence' and 'choice' don't seem to provide such options.
Please, is there a way to achieve what I am looking for?
Many thanks in advance.
PS Apologies for the formatting, I just could not get it to wrap and indent correctly.
If you need to do this in XSD 1.0 I believe it can be expressed as
sequence
element name=BlockB min=0 max=unbounded
element name=BlockA min=1 max=1
choice min=0 max=unbounded
element name=BlockA min=1 max=1
element name=BlockB min=1 max=1
I tested your code and a solution is replacing the xs:sequence
by xs:all
. Unfortunately this solution works only in XSD-1.1, because XSD-1.0 has the restriction that maxOccurs
can only be 0
or 1
(see comments below).
<xs:complexType name="blocks">
<xs:all>
<xs:element name="BlockA" type="blockA" minOccurs="1" maxOccurs="unbounded"/>
<xs:element name="BlockB" type="blockB" minOccurs="0" maxOccurs="unbounded" />
</xs:all>
<xs:attribute name="Name" type="xs:string" use="required" />
<xs:attribute name="Use" type="xs:boolean" use="required" />
</xs:complexType>
This has worked in my example code.
EDIT:
I used the following XSD as a test-case:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema
elementFormDefault="unqualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root" type="blocks" />
<xs:complexType name="blocks">
<xs:all>
<xs:element name="BlockA" type="blockA" minOccurs="1" maxOccurs="unbounded"/>
<xs:element name="BlockB" type="blockB" minOccurs="0" maxOccurs="unbounded" />
</xs:all>
<xs:attribute name="Name" type="xs:string" use="required" />
<xs:attribute name="Use" type="xs:boolean" use="required" />
</xs:complexType>
<xs:simpleType name="blockA">
<xs:restriction base="xs:string" />
</xs:simpleType>
<xs:simpleType name="blockB">
<xs:restriction base="xs:string" />
</xs:simpleType>
</xs:schema>
And my example code samples were the following:
-
for this code:
<root Name="ThisIsAName" Use="true">
<BlockB>DEF</BlockB>
<BlockA>ABC</BlockA>
<BlockA>ABC</BlockA>
<BlockA>ABC</BlockA>
<BlockA>ABC</BlockA>
<BlockB>DEF</BlockB>
</root>
===> VALID!!!
-
for this code:
<root Name="ThisIsAName" Use="true">
<BlockA>ABC</BlockA>
<BlockA>ABC</BlockA>
</root>
===> VALID!!!
-
for this code:
<root Name="ThisIsAName" Use="true">
<BlockB>DEF</BlockB>
<BlockB>DEF</BlockB>
</root>
===> FAIL!!!
-
for this code:
<root Name="ThisIsAName" Use="true">
</root>
===> FAIL!!!
So with XSD-1.1 everything does work.