tags:

views:

166

answers:

2

Edit: This is not a dupe of my last question as I didn't want to do both at the same time anymore.

I want to specify that my setting node has either :

   <setting name='Some Setting'>
      SomeData
    </setting>

schema is :

  <xs:element name="setting">
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base="xs:string">
          <xs:attribute name="name" type="xs:string" use="required" />
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>

or

  <setting name='Some Setting'>
    <value>SomeData</value>
  </setting>

schema is:

<xs:element minOccurs="0" name="setting">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="value" type="xs:string" />
    </xs:sequence>
    <xs:attribute name="name" type="xs:string" use="required" />
  </xs:complexType>
</xs:element>

but not both.

I can't figure out how to combine them in the overall schema. I've tried using <xs:choice /> but that complains that the elements with the same name need be of the same type

A: 

These types of restrictions aren't possible to describe in XSD, you'll need to use another language to model them, e.g. schematron.

superfell
thank you for clarifying this
Preet Sangha
+1  A: 

I think the closest you're going to get is to use mixed="true", like this:

<xs:complexType>
  <xs:sequence>
    <xs:element name="setting">
      <xs:complexType mixed="true">
        <xs:sequence>
          <xs:element name="value" type="xs:string" minOccurs="0" />
        </xs:sequence>
        <xs:attribute name="name" type="xs:string" use="required" />
      </xs:complexType>
    </xs:element>
  </xs:sequence>
</xs:complexType>

This allows you to have a combination of simple content and a value element.

With this schema, the following XML would be considered valid:

  1. Simple content only:

    <setting name="Some Setting">SomeData</setting>
    
  2. Sub-element only:

    <setting name="Some Setting">
      <value>SomeData</value>
    </setting>
    
  3. Both:

    <setting name="Some Setting">
      Some Data
      <value>SomeData</value>
    </setting>
    

The possibility of (3) is definitely not ideal, but I don't think you can avoid it. You will need to have a rule that deals with this situation. I think a reasonable rule would be: if a value element is present, use the data between the value tags, otherwise use the data between the setting tags.

DanM
Thank you for answer. I shall try this out today. I know mixed nodes are discouraged but it looks like the best solution for me.
Preet Sangha