Search code examples
xmlxsdxsd-1.0

How to ensure at least one child element exists via XSD?


How can I ensure than at least one of location's child elements (locality, wkt) is specified when the location element is included in an XML?

<xs:element name="location" nillable="true" minOccurs="0">
  <xs:complexType>
    <xs:group ref="cs:locationGroup"></xs:group>
  </xs:complexType>
</xs:element>

Definition of locationGroup:

<xs:group name="locationGroup">
  <xs:all>
    <xs:element name="locality" minOccurs="0"/>
    <xs:element name="wkt" minOccurs="0"/>
  </xs:all>
</xs:group>

The version of my XSD is 1.0.


Solution

  • For such a small number of possible child elements, simply define a xs:choice of the allowed combinations:

    <?xml version="1.0" encoding="utf-8"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    
      <xs:element name="location">
        <xs:complexType>
          <xs:group ref="locationGroup"></xs:group>
        </xs:complexType>
      </xs:element>
    
      <xs:group name="locationGroup">
        <xs:choice>
          <xs:sequence>
            <xs:element name="locality"/>
            <xs:element name="wkt" minOccurs="0"/>
          </xs:sequence>
          <xs:sequence>
            <xs:element name="wkt"/>
            <xs:element name="locality" minOccurs="0"/>
          </xs:sequence>
        </xs:choice>
      </xs:group>
    </xs:schema>
    

    Note that this approach

    • requires one or both of locality or wkt to be present
    • allows any order when both are present
    • works in both XSD 1.0 (and 1.1)

    as requested.