brandstaetter
brandstaetter

Reputation: 912

XML Schema: require an element to be present when another is present

My Schema allows a specific element to be optional, but when I encounter a different also optional element later on in the file, I need the previous one to be present. How can I ensure this via XSD?

Example:

<settings>
  <file name="narf.txt"/>
  <metafile name="narf.meta"/>
  <filtermeta>true</filtermeta>
</settings>

should be valid,

<settings>
  <file name="narf.txt"/>
  <metafile name="narf.meta"/>
</settings>

and

<settings>
  <file name="narf.txt"/>
</settings>

should be valid too,

<settings>
  <file name="narf.txt"/>
  <filtermeta>true</filtermeta>
</settings>

should not be valid.

Upvotes: 3

Views: 4071

Answers (2)

Tony L
Tony L

Reputation: 11

You could have filtermeta as an optional attribute to the metafile element.

Upvotes: 0

Martin Rist
Martin Rist

Reputation: 101

Try the following schema definition:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
  <xs:element name="settings">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="file">
          <xs:complexType>
            <xs:attribute name="name" type="xs:string"/>
          </xs:complexType>
        </xs:element>
        <xs:sequence minOccurs="0">
          <xs:element name="metafile">
            <xs:complexType>
              <xs:attribute name="name" type="xs:string"/>
            </xs:complexType>
          </xs:element>
          <xs:element minOccurs="0" name="filtermeta" type="xs:string"/>
        </xs:sequence>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

I've run your first three examples against this schema using xmllint and they validate correctly. The fourth example fails with:

cvc-complex-type.2.4.a: Invalid content was found starting with element 'filtermeta'. One of '{metafile}' is expected.

as expected.

Upvotes: 3

Related Questions