tags:

views:

134

answers:

1

Hi

I've got this problem and I can't for the life of me find a simple solution.

I am trying to codify a list of operating systems, where the XML file contains a list of the OSes that a given person has. There is a fixed list of OSes (XP, Vista, Win7, OSX and Ubuntu).
I have the following piece of XML

<operatingSystems>
   <operatingSystem name="Windows XP" />
   <operatingSystem name="Windows Vista" />
   <operatingSystem name="Windows 7" />
   <operatingSystem name="OS X" />
   <operatingSystem name="Ubuntu Linux" />
</operatingSystems>

The <operatingSystems> element can contain 0 or more of the operating systems listed.

So valid examples would be:

<operatingSystems>
   <operatingSystem name="Windows XP" />
   <operatingSystem name="OS X" />
   <operatingSystem name="Ubuntu Linux" />
</operatingSystems>

or

<operatingSystems />

I am trying to write an XSD schema to validate this. My questions is what is the best way to go about validating that the <operatingSystems> element only contains child <operatingSystem> elements where the name is from the given set and that each name element does not appear more than once.

Invalid examples would be:

<operatingSystems>
   <operatingSystem name="OS X" />
   <operatingSystem name="OS X" />
   <operatingSystem name="Ubuntu Linux" />
</operatingSystems>

or

<operatingSystems>
   <operatingSystem name="Sun Solaris" />
</operatingSystems>

Ive tried this:

<element name="operatingSystems">
  <complexType>
    <sequence>
       <element name="operatingSystem" minOccurs="0" maxOccurs="1">
         <complexType>
           <attribute name="name" fixed="Windows XP" />
         </complexType>
       </element>
       <element name="operatingSystem" minOccurs="0" maxOccurs="1">
         <complexType>
           <attribute name="name" fixed="Windows Vista" />
         </complexType>
       </element>
      .......
     </sequence>
   </complexType>
</element>

but it ingores the fact that minOccurs is 0 and will complain if any element operating system is missing.

Any help would be appreciated.

Thanks

A: 

You could use xs:unique element:

<xs:element name="operatingSystems">
  <xs:complexType>
    <xs:sequence>
      <xs:element ref="operatingSystem" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>
  <xs:unique name="oneOperatingSystem">
    <xs:selector xpath="operatingSystem"/>
    <xs:field xpath="@name"/>
  </xs:unique>
</xs:element>
<xs:element name="operatingSystem">
  <xs:complexType>
    <xs:attribute name="name" use="required">
      <xs:simpleType>
        <xs:restriction base="xs:token">
          <xs:enumeration value="Windows XP"/>
          <xs:enumeration value="Windows Vista"/>
          <xs:enumeration value="Windows 7"/>
          <xs:enumeration value="OS X"/>
          <xs:enumeration value="Ubuntu Linux"/>
        </xs:restriction>
      </xs:simpleType>
    </xs:attribute>
  </xs:complexType>
</xs:element>
jelovirt