XSD: choice based on the condition of an element

I'm trying to come up with an XSD for this kind of XML:

<root>
  <valid>
    <a>1</a>
    <b>foo</b>
    <c>bar</c>
  </valid>
  <valid>
    <a>2</a>
    <c>bar</c>
    <d1>baz</d1>
  </valid>
  <valid>
    <a>3</a>
    <c>bar</c>
    <d2>baz-restricted</d2>
    <e>qux</e>
  </valid>
</root>

In all elements named valid, each child-element is mandatory.

I know I need to make the xs:choice conditional on the value of a, as the below XSD is ambiguous at the second occurence of c.

How can this be done in the XSD supported by .NET 4.x?

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
  <xs:element name="root">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="valid">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="a" minOccurs="1" maxOccurs="1"/>
              <xs:choice>
                <xs:sequence>
                  <xs:element name="b" minOccurs="1" maxOccurs="1"/>
                  <xs:element name="c" minOccurs="1" maxOccurs="1"/>
                </xs:sequence>
                <xs:sequence>
                  <xs:element name="c" minOccurs="1" maxOccurs="1"/>
                  <xs:element name="d1" minOccurs="1" maxOccurs="1"/>
                </xs:sequence>
                <xs:sequence>
                  <xs:element name="c" minOccurs="1" maxOccurs="1"/>
                  <xs:element name="d2" minOccurs="1" maxOccurs="1"/>
                  <xs:element name="e" minOccurs="1" maxOccurs="1"/>
                </xs:sequence>
              </xs:choice>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

(I know the XSD nested might be better off using custom types. If needed, I can make it custom, just let me know if it is in fact needed for a solution and I will).

Upvotes: 2

Views: 1633

Answers (1)

kjhughes
kjhughes

Reputation: 111630

In all elements named valid, each child-element is mandatory.

You cannot have same-named sibling elements be of different types in XSD 1.0.

You could use conditional type assignment in XSD 1.1 to do this, except...

How can this be done in the XSD supported by .NET 4.x

...Microsoft does not support XSD 1.1. You might consider using Saxon for .NET instead.

If you cannot switch to Saxon or another environment where XSD 1.1 is supported, either loosen your validation constraints or give the different versions of valid different names to reflect their different types.

Upvotes: 2

Related Questions