Dusty Phillips
Dusty Phillips

Reputation: 113

XML Schema: Permit a tag only if another optional tag is provided

I'm trying to define an XML schema that has an optional tag, sort_expression. If that optional tag is provided, then a second optional tag, alternate_sort_expression is allowed, but it is conditional on the existence of the first tag.

For example, I want these examples to validate:

<indication>
    <label>A label for the item</label>
    <sort_expression>Some Value</sort_expression>
    <!-- one sort expression was provided -->
</indication>

or

<indication>
    <label>A label for the item</label>
    <!-- no sort expression was provided -->
</indication>

or

<indication>
    <label>A label for the item</label>
    <sort_expression>Some Value</sort_expression>
    <alternate_sort_expression>Some Value</alternate_sort_expression>
</indication>

but the following should not pass validation:

<indication>
    <label>A label for the item</label>
    <!-- no main sort expression was provided -->
    <alternate_sort_expression>INVALID</alternate_sort_expression>
</indication>

I thought the following schema, using a choice of two sequences would work. Unfortunately the schema itself is not validating; Altova XML Spy is telling me "the content model of complex type indication is ambiguous:

<xs:complexType name="indication">
<xs:sequence>
  <xs:element name="label" type="xs:string"/>
  <xs:choice>
    <xs:sequence>
      <xs:element name="sort_expression" type="xs:string" minOccurs="0"/>
    </xs:sequence>
    <xs:sequence>
      <xs:element name="sort_expression" type="xs:string"/>
      <xs:element name="alternate_sort_expression" type="xs:string" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:choice>
</xs:sequence>

Upvotes: 1

Views: 370

Answers (2)

jasso
jasso

Reputation: 13966

Create an optional sequence that contains a mandatory <sort_expression> element and optional <alternate_sort_expression> elements.

Because they are in the same sequence, <alternate_sort_expression> appears only when <sort_expression> is present but also <sort_expression> can be omitted because the whole sequence can be omitted.

<xs:complexType name="indication">
  <xs:sequence>
    <xs:element name="label" type="xs:string"/>
    <xs:sequence minOccurs="0">
      <xs:element name="sort_expression" type="xs:string"/>
      <xs:element name="alternate_sort_expression" minOccurs="0" maxOccurs="unbounded" type="xs:string"/>
    </xs:sequence>
  </xs:sequence>
</xs:complexType>

Upvotes: 4

Filburt
Filburt

Reputation: 18061

This would be possible using nested sequences:

<xs:complexType>
    <xs:sequence>
        <xs:element name="label" type="xs:string" />
        <xs:sequence minOccurs="0" maxOccurs="1">
            <xs:element name="sort_expression" type="xs:string" />
            <xs:sequence minOccurs="0" maxOccurs="unbounded">
                <xs:element name="alternate_sort_expression" type="xs:string" />
            </xs:sequence>
        </xs:sequence>
    </xs:sequence>
</xs:complexType>

... at least it validates your examples as desired.

Upvotes: 1

Related Questions