1

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.

PeerBr
  • 675
  • 1
  • 11
  • 26
  • 1
    Sadly, there are many things that XMLSpy thinks are valid, but are not. XMLSpy is buggy as hell. – skaffman Sep 08 '10 at 13:57
  • For exactly that reason he should try the w3c validator... – oopbase Sep 08 '10 at 14:05
  • @Forlan07 Could you provide the link to the w3c validator for validating using a schema? I've only found some experimental stuff and DTD validation. Thanks! – PeerBr Sep 08 '10 at 14:55

3 Answers3

3

Briefly

  1. Document is valid because elements have minOccurs="0".
  2. Use <xs:choice> instead of <xs:sequence>.

A bit longer answer.

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.

Community
  • 1
  • 1
jasso
  • 13,736
  • 2
  • 36
  • 50
  • Thank you for the very good explanation. As stated above, I followed that without changing the minOccurs either for xs:choice nor xs:element. That had the effect I wanted: Any two items or more, in any order. – PeerBr Sep 10 '10 at 22:46
  • So does `filterElement` and `or` still have `minOccurs="0"` in your schema? If so, then your original document would still be valid (which you didn't want to happen) even if you used `` because `minOccurs="0"` on the element definitions allows the validator to select an element 0 times. – jasso Sep 12 '10 at 14:51
2

You have a minOccurs="0" on filterElement. So a single filterElement can be seen as a filterElement 0 times, followed by a filterElement. A valid sequence. Maybe you should avoid mixing minOccurs in xs:sequence and xs:element in your schema...

Damien
  • 3,060
  • 1
  • 25
  • 29
  • I changed the structure to xs:choice and it worked. I don't get your explanation, though. I'll do some reading on these constructors. Thanks! – PeerBr Sep 08 '10 at 20:19
0

You have a sequence that must occur twice, but elements in the sequence are optional (minOccurs="0"). The sequence itself doesn't represent any XML, it just defines the possible elements it can contain and the order they must be in. A perfectly valid sequence can be empty in that case.

Replacing <xs:sequence> with <xs:choice> and changing minOccurs to 1 on the subelements will work if you do not care what order the elements appear in and it looks like you don't. If you don't set minOccurs to 1 on the children then a valid choice would still be the element occurring 0 times and your XML would validate. If you set minOccurs to 2 on the child elements then you would have a minimum of 4 elements since you would make a choice twice and pick from each child element occurring twice each time.

Jason Goemaat
  • 28,692
  • 15
  • 86
  • 113
  • Thanks for your answer as well! I really get the subtleties of xs:choice now, that helped a lot. – PeerBr Sep 10 '10 at 22:48