Search code examples
xmlxsd

XSD - Need two separate choice options


I am writing some XSD and I only have a basic understanding of the <choice> tag. I have it working with one section, but not another section that has an attribute.

For example, all elements are optional, but if I don't have one, then I need to have the other. This is fine if there is 2 elements, but I have 3.

Look at the schema section below. I can either have message or scan and not include, or I can have include and not message or scan.

       <xs:element name="messages">
        <xs:complexType>
          <xs:sequence>
            <xs:element minOccurs="0" ref="n:properties"/>

        <xs:choice>
          <xs:sequence>
            <xs:element ref="n:message" maxOccurs="unbounded"/>
            <xs:element ref="n:scan" minOccurs="0"/>
          </xs:sequence>

          <xs:element ref="n:scan"/>
        </xs:choice>

              <xs:attribute name="include"/>
          </xs:sequence>
        </xs:complexType>

  </xs:element>

At the moment, this is working for message and scan but gives me an error on include obviously, because I don't have the choice put in there yet.

Can anyone show me some samples of how I'd do (message OR scan) OR include?

Thanks


Solution

  • By far the simplest way to say "either A or B or C" is to make A, B, and C all be elements and write

    <xs:choice>
      <xs:element ref="A"/>
      <xs:element ref="B"/>
      <xs:element ref="C"/>
    </xs:choice>
    

    An alternative would be to say "including messages from another file is not the same as specifying a message" and define both n:messages (which contains either a message or a scan) and n:message-inclusion (which points to another file). In the parent element allow either. Or define an abstract message-thingy element and put n:messages and n:message-inclusion into its substitution group.

    A second alternative: move to XSD 1.1 and use an assertion to enforce the rule that the include attribute is present iff the children are absent.