Value-equals test required

From W3C Wiki

Value-equals test required (a co-constraint use case)

Allow one attribute to be required if the value of another attribute is a particular named value; otherwise forbidden.

Cf. Attribute mutex and Simple attribute implication (which make the required/optional/forbidden status of one attribute depend on the presence or absence, rather than the value, of the other attribute).

Source: [1]


Other use cases: Co-constraint Use Cases

Description

   Does XML handle conditional structure?
   In otherwords, can the use of a type be conditional?
   Please see the following example.


     <xsd:complexType name="BindType">
       <xsd:attribute name="type" use="required">
         <xsd:simpleType>
           <xsd:restriction base="xsd:NMTOKEN">
             <xsd:enumeration value="BridgedEthernet"/>
             <xsd:enumeration value="PPPOE"/>
           </xsd:restriction>
         </xsd:simpleType>
       </xsd:attribute>
    
       <!-- the following item is required if value of above attribute "type"
       is "BridgeEthernet" : can this be done ???? -->
       <xsd:attribute name="BrEthernetIP" use="optional">
         <xsd:simpleType>
           <xsd:restriction base="xsd:string">
             <xsd:minLength value="7"/>
             <xsd:maxLength value="16"/>
           </xsd:restriction>
         </xsd:simpleType>
       </xsd:attribute>
     </xsd:complexType>


Analysis

FV

This is a value-based condition on an Attribute generating an upgrade of another attribute. Axis is attribute.

CoConstraintDimensionSource:
CoConstraintDimensionDestination:
CoConstraintDimensionType:
CoConstraintDimensionEffect:
CoConstraintDimensionAxis:

Possible solutions

Relax NG

Schematron

Check clause

One solution (proposal 1) is to add this annotation to the complex type.

  <xsd:annotation>
   <xsd:appinfo>
    <sch:pattern>
     <sch:rule>
      <sch:report 
       test="@type='BridgeEthernet' & @BrEthernetIP = ''">
       If BindType/@type is 'BridgeEthernet', then a value is required
       for the BrEthernetIP attribute.
      </sch:report>
     </sch:rule>
    </sch:pattern>
   </xsd:appinfo>
  </xsd:annotation>

Another (proposal 2) would be to include the sch:report element directly in the complex type definition.

Note that to the extent that the user conceives of this as a constraint on the BrEthernetIP attribute, any expression as a constraint on the containing complex type will feel misplaced.

SchemaPath

One of the possible solutions is:


     <xsd:element name="Bind">
       <xsd:alt cond="./@type='BridgedEthernet'" type="TBridged"/>
       <xsd:alt                                  type="TPPPOE"/>
     </xsd:element>

     <xsd:complexType name="TBridged">
       <xsd:attribute name="type"         use="required" type="xsd:NMTOKEN"    fixed="BridgedEthernet">
       <xsd:attribute name="BrEthernetIP" use="required" type="SevenSixteen"/>
     </xsd:complexType>

     <xsd:complexType name="TPPPOE">
       <xsd:attribute name="type"         use="required" type="xsd:NMTOKEN"    fixed="PPPOE">
     </xsd:complexType>

     <xsd:simpleType name="SevenSixteen">
       <xsd:restriction base="xsd:string">
          <xsd:minLength value="7"/>
          <xsd:maxLength value="16"/>
       </xsd:restriction>
     </xsd:simpleType>


and another is:


     <xsd:element name="Bind">
       <xsd:alt cond="./@type='BridgedEthernet' and not ./@BrEthernetIP" type="xsd:error"/>
       <xsd:alt                                                          type="BindType">
     </xsd:element>

     <xsd:complexType name="BindType">
       <xsd:attribute name="type" use="required">
         <xsd:simpleType>
           <xsd:restriction base="xsd:NMTOKEN">
             <xsd:enumeration value="BridgedEthernet"/>
             <xsd:enumeration value="PPPOE"/>
           </xsd:restriction>
         </xsd:simpleType>
       </xsd:attribute>
       <xsd:attribute name="BrEthernetIP" use="optional">
         <xsd:simpleType>
           <xsd:restriction base="xsd:string">
             <xsd:minLength value="7"/>
             <xsd:maxLength value="16"/>
           </xsd:restriction>
         </xsd:simpleType>
       </xsd:attribute>
     </xsd:complexType>


Conditional Type

Inventing a syntax:


     <xsd:complexType name="BindType">
       <xsd:alt cond="./@type='BridgedEthernet'">
         <xsd:attribute name="type"         use="required" type="xsd:NMTOKEN" fixed="BridgedEthernet"/>
         <xsd:attribute name="BrEthernetIP" use="optional" type="SevenSixteen"/>
       </xsd:alt>
       <xsd:alt>
         <xsd:attribute name="type"         use="required" type="xsd:NMTOKEN" fixed="PPPOE"/>
       </xsd:alt>
     </xsd:complexType>

     <xsd:simpleType name="SevenSixteen">
       <xsd:restriction base="xsd:string">
          <xsd:minLength value="7"/>
          <xsd:maxLength value="16"/>
       </xsd:restriction>
     </xsd:simpleType>