Search code examples
xmlxsdxsd-validationxml-validation

Limit number of elements with attribute via XSD?


There is a fragment of XML

<items>
    <itemUID>uid-1</itemUID>
    <itemUID>uid-2</itemUID>
    <itemUID key="true">uid-3</itemUID>
    <itemUID>uid-4</itemUID>
    <itemUID>uid-5</itemUID>
    <itemUID key="true">uid-6</itemUID>
    <itemUID>uid-7</itemUID>
</items>

Rule: Element items can contain from 1 to unbounded elements itemUID, but only 0 or 2 or 3 elements with attribute key.

Can I define this rule with XSD restrictions only?


Solution

  • You cannot express your constraint in XSD 1.0, but in XSD 1.1, you can use xs:assert to limit the itemUID elements with key attributes to 0, 2, 3 elements as follows:

      <xs:assert test="count(itemUID[@key]) = (0, 2, 3)"/>
    

    Here it is in context in a complete XSD:

    XSD 1.1

    <?xml version="1.0" encoding="UTF-8"?>
    <xs:schema attributeFormDefault="unqualified" 
      elementFormDefault="qualified" 
      xmlns:xs="http://www.w3.org/2001/XMLSchema"
      xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
      vc:minVersion="1.1">
    
      <xs:element name="items">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="itemUID" minOccurs="1" maxOccurs="unbounded">
               <xs:complexType>
                 <xs:simpleContent>
                   <xs:extension base="xs:string">
                     <xs:attribute name="key" type="xs:boolean">
                     </xs:attribute>
                   </xs:extension>
                 </xs:simpleContent>
               </xs:complexType>
            </xs:element>
          </xs:sequence>
          <xs:assert test="count(itemUID[@key]) = (0, 2, 3)"/>
        </xs:complexType>
      </xs:element>
    </xs:schema>