XSD 1.0
You cannot directly represent your constraint in XML Schema 1.0. You could use Schematron or check it at the application level. You could also rewrite your XSD to allow two types of items: item
which does not allow metadata
and item_meta
which requires it:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="items">
<xs:complexType>
<xs:choice>
<xs:element ref="item" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="item_meta" minOccurs="0" maxOccurs="unbounded"/>
</xs:choice>
</xs:complexType>
</xs:element>
<xs:group name="commonItemElements">
<xs:sequence>
<xs:element name="id"/>
<xs:element name="filename"/>
<xs:element name="file_url"/>
</xs:sequence>
</xs:group>
<xs:element name="item">
<xs:complexType>
<xs:group ref="commonItemElements"/>
</xs:complexType>
</xs:element>
<xs:element name="item_meta">
<xs:complexType>
<xs:sequence>
<xs:group ref="commonItemElements"/>
<xs:element name="metadata"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
XSD 1.1
In XML Schema 1.1, you can specify co-occurrence constraints via XPath 2.0 using xs:assert
to constrain the number of optional metadata
elements to be 0 or equal to the number of item
elements:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="items">
<xs:complexType>
<xs:sequence>
<xs:element ref="item" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:assert test="(count(item/metadata) = 0) or (count(item/metadata) = count(item))"/>
</xs:complexType>
</xs:element>
<xs:element name="item">
<xs:complexType>
<xs:sequence>
<xs:element name="id"/>
<xs:element name="filename"/>
<xs:element name="file_url"/>
<xs:element name="metadata" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>