I am writing some XSD and I only have a basic understanding of the <choice>
tag. I have it working with one section, but not another section that has an attribute
.
For example, all elements are optional, but if I don't have one, then I need to have the other. This is fine if there is 2 elements, but I have 3.
Look at the schema section below. I can either have message
or scan
and not include
, or I can have include
and not message
or scan
.
<xs:element name="messages">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" ref="n:properties"/>
<xs:choice>
<xs:sequence>
<xs:element ref="n:message" maxOccurs="unbounded"/>
<xs:element ref="n:scan" minOccurs="0"/>
</xs:sequence>
<xs:element ref="n:scan"/>
</xs:choice>
<xs:attribute name="include"/>
</xs:sequence>
</xs:complexType>
</xs:element>
At the moment, this is working for message
and scan
but gives me an error on include
obviously, because I don't have the choice put in there yet.
Can anyone show me some samples of how I'd do (message OR scan) OR include
?
Thanks
By far the simplest way to say "either A or B or C" is to make A, B, and C all be elements and write
<xs:choice>
<xs:element ref="A"/>
<xs:element ref="B"/>
<xs:element ref="C"/>
</xs:choice>
An alternative would be to say "including messages from another file is not the same as specifying a message" and define both n:messages
(which contains either a message
or a scan
) and n:message-inclusion
(which points to another file). In the parent element allow either. Or define an abstract message-thingy
element and put n:messages
and n:message-inclusion
into its substitution group.
A second alternative: move to XSD 1.1 and use an assertion to enforce the rule that the include
attribute is present iff the children are absent.