Please enlighten me why XML Spy thinks this is valid. FYI, this specifies an SQL query. Here the XML:
<sideBar title="LabelSearch">
<searchLabel table="ID=*.companies">
<filter accessRight="r">
<and>
<filterElement argument="companies.Type" operator="=" value="Client"/>
</and>
</filter>
</searchLabel>
</sideBar>
The problem: I should not be allowed to put in only one filterElement inside the "and" tag, but at least two. If I only have one filterElement, I should use it without the surrounding "and" tag. Here the XSD:
<xs:complexType name="filterGroupType">
<xs:sequence>
<xs:choice>
<xs:element name="or" type="filterGroupOrType"/>
<xs:element name="and" type="filterGroupAndType"/>
<xs:element name="filterElement" type="filterType"/>
</xs:choice>
</xs:sequence>
<xs:attribute name="accessRight" type="accessRightSimpleType" use="required"/>
</xs:complexType>
<xs:complexType name="filterGroupAndType">
<xs:sequence minOccurs="2" maxOccurs="unbounded">
<xs:element name="or" type="filterGroupOrType" minOccurs="0"/>
<xs:element name="filterElement" type="filterType" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="filterGroupOrType">
<xs:sequence minOccurs="2" maxOccurs="unbounded">
<xs:element name="and" type="filterGroupAndType" minOccurs="0"/>
<xs:element name="filterElement" type="filterType" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="filterType">
<xs:attribute name="argument" type="xs:string" use="required"/>
<xs:attribute name="operator" type="operatorSimpleType" use="required"/>
<xs:attribute name="value" type="xs:anySimpleType"/>
<xs:attribute name="field" type="fieldTitleSimpleType"/>
</xs:complexType>
Thanks in advance.
minOccurs="0"
.<xs:choice>
instead of <xs:sequence>
.Just like @Damien said, that XML is valid because this part of your schema allows "empty" sequences.
<xs:sequence minOccurs="2" maxOccurs="unbounded">
<xs:element name="or" type="filterGroupOrType" minOccurs="0"/>
<xs:element name="filterElement" type="filterType" minOccurs="0"/>
</xs:sequence>
With <xs:sequence minOccurs="2" maxOccurs="unbounded">
You define that "this sequence must appear at least twice". At the same time <xs:element name="or" type="filterGroupOrType" minOccurs="0"/>
Allows these elements within the sequence to be absent. Metaphorically it is like saying "You must order a meal twice but you don't have to eat any of the meals you ordered."
Instead if you want to always have at least 2 child elements and these children can be<filterElement>
or <or>
elements in any order, you should use <xs:choice>
with minOccurs="1"
<xs:choice minOccurs="2" maxOccurs="unbounded">
<xs:element name="or" type="filterGroupOrType" minOccurs="1"/>
<xs:element name="filterElement" type="filterType" minOccurs="1"/>
</xs:choice>
The default value for minOccurs
is 1 so you can leave it out and keep your code cleaner and shorter. <xs:choice>
selects one of its children and repeats choosing at least minOccurs
times. If at least one of choices can has minOccurs="0"
then the choice will also allow "empty" selections.