Reputation: 645
I'm writing a Schema for our (old) XML output, and have run into an issue where an element may contain some sub-elements. I'm using an "xs:all minOccurs="0" in the schema, but when I validate against the XML, it's requiring at least one instance of each sub-element.
<xs:element name="Project">
<xs:complexType>
<xs:all minOccurs="0" maxOccurs="1">
<xs:element ref="lit:ProductPool" minOccurs="1"/>
<xs:element ref="lit:ProjectDefaults"/>
<xs:element ref="lit:TaskInfo"/>
</xs:all>
<xs:attribute name="Name" type="lit:TextType_2010"/>
... a bunch more
Then when I use that to validate some XML that only has the "ProductPool" sub element, the validator complains that the other 2 are missing and are required.
Reason: The following elements are expected after this location (see below)
'lit:TaskInfo'
'lit:ProjectDefaults'
Error location: MetrixXML / Project
Details
cvc-complex-type.1.4: The content for element <Project> is incomplete.
cvc-type.3.2: Element <Project> is not valid with respect to type definition '{anonymous}'.
cvc-elt.5.2.1: The element <Project> is not valid with respect to the actual type definition '{anonymous}'.```
Upvotes: 1
Views: 4379
Reputation: 159096
On an <xs:element>
*, the value of attributes minOccurs
and maxOccurs
both default to 1
.
On an <xs:all>
*, the value of attributes minOccurs
and maxOccurs
both default to 1
.
* Click link to see specification
That means the follow 3 constructs are the same:
<!-- As defined in question -->
<xs:all minOccurs="0" maxOccurs="1">
<xs:element ref="lit:ProductPool" minOccurs="1"/>
<xs:element ref="lit:ProjectDefaults"/>
<xs:element ref="lit:TaskInfo"/>
</xs:all>
<!-- Without specifying values that are same as defaults -->
<xs:all minOccurs="0">
<xs:element ref="lit:ProductPool"/>
<xs:element ref="lit:ProjectDefaults"/>
<xs:element ref="lit:TaskInfo"/>
</xs:all>
<!-- Specifying values, even if same as defaults -->
<xs:all minOccurs="0" maxOccurs="1">
<xs:element ref="lit:ProductPool" minOccurs="1" maxOccurs="1"/>
<xs:element ref="lit:ProjectDefaults" minOccurs="1" maxOccurs="1"/>
<xs:element ref="lit:TaskInfo" minOccurs="1" maxOccurs="1"/>
</xs:all>
This means that if the all
is used in the actual XML, by having any of ProductPool
, ProjectDefaults
, or TaskInfo
present, then all 3 must be present.
The minOccurs="0"
means that you can have none of them, or all three of them.
Perhaps you believed that minOccurs
defaulted to 0
, in which case you should have written it like this:
<xs:all minOccurs="0">
<xs:element ref="lit:ProductPool"/>
<xs:element ref="lit:ProjectDefaults" minOccurs="0"/>
<xs:element ref="lit:TaskInfo" minOccurs="0"/>
</xs:all>
With such a definition, ProductPool
is optional, and can appear by itself. ProjectDefaults
and TaskInfo
are also optional, but if either is present, then ProductPool
is required. The three elements can appear in any order.
Upvotes: 1
Reputation: 11527
That is because your MinOccurs is on the All node rather than on the ProjectDefaults or TaskInfo, by default they will be minOccurs once. So if ProductPool was not there, it will not complain, but as soon as you have ProductPool, it will expect the other two.
Resolve it by setting MinOccurs = 0
on ProjectDefaults and TaskInfo
Upvotes: 2