Search code examples
phpxmlxsdxsd-1.0

One or more elements, at least one with given value for an attribute


I need to describe following in an XML schema: one element must occur 1 or more times, but exactly one occurrence of this element must have the attribute "properties" set to value "nav"

Example:

<manifest>
    <item href="example" id="02" properties="cover-image" /> <!-- optional item -->
    <item href="dummy" id="sample" properties="nav" /> <!-- mandatory item with "nav" value for "properties" attribute -->
    <item href="example" id="02" properties="mathlm scripted" /> <!-- optional item -->
</manifest> 

My "best" try was:

    <xs:element name="manifest">
      <xs:complexType>
        <xs:choice>
          <xs:element name="item" minOccurs="1" maxOccurs="1" ><!-- at least one (item property="nav")-->
            <xs:complexType>
              <xs:attribute name="href" type="xs:string" use="required" />
              <xs:attribute name="id" type="xs:string" use="required" />
              <xs:attribute name="media-type" type="xs:string" use="required" />
              <xs:attribute name="fallback" type="xs:string" />
              <xs:attribute name="properties" type="xs:string" use="required" fixed="nav" />
              <xs:attribute name="media-overlay" type="xs:string" />
            </xs:complexType>
          </xs:element>
          <xs:element name="item" minOccurs="0" maxOccurs="unbounded" >
            <xs:complexType>
              <xs:attribute name="href" type="xs:string" use="required" />
              <xs:attribute name="id" type="xs:string" use="required" />
              <xs:attribute name="media-type" type="xs:string" use="required" />
              <xs:attribute name="fallback" type="xs:string" />
              <xs:attribute name="properties" type="xs:string" />
              <xs:attribute name="media-overlay" type="xs:string" />
            </xs:complexType>
          </xs:element>
        </xs:choice>
        <xs:attribute name="id" type="xs:string" />
      </xs:complexType>
    </xs:element>

Bad try though, since validator gives me following error:

local complex type: The content model is not determinist.

It's clear that this schema isn't deterministic, since the validator can't decide if he is supposed to check the encountered item element with the first or the second of the 2 definitions for this element...
...but how can I achieve this? Is this possible at all ?


Solution

  • This can't be achieved using XSD 1.0, it requires XSD 1.1 and assertions. I don't think your default schema validator in PHP will support XSD 1.1.