Re: XML schema supports conditional structure???

Hi,

> Does XML handles 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>

Unfortunately you can't do these conditional relationships with the current
version of W3C XML Schema but it probably will be supported in the next
version. However, in the mean time we have to use other means to achieve
these kinds of constraints and one way to do it is to combine Schematron
with W3C XML Schema. What you do is to include a Schematron rule in the
xs:appinfo element of your XML Schema and for your constraint above it could
look like this:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified" attributeFormDefault="unqualified">
 <xs:element name="Root" type="BindType"/>
 <xs:complexType name="BindType">
  <xs:annotation>
   <xs:appinfo>
    <pattern name="Bridged Option"
xmlns="http://www.ascc.net/xml/schematron">
     <rule context="*[@type = 'BridgedEthernet']">
      <assert test="@BrEthernetIP">If attribute @type = 'BridgedEthernet'
the attribute @BrEthernetIP must be present.</assert>
     </rule>
    </pattern>
   </xs:appinfo>
  </xs:annotation>
  <xs:attribute name="type" use="required">
   <xs:simpleType>
    <xs:restriction base="xs:NMTOKEN">
     <xs:enumeration value="BridgedEthernet"/>
     <xs:enumeration value="PPPOE"/>
    </xs:restriction>
   </xs:simpleType>
  </xs:attribute>
  <xs:attribute name="BrEthernetIP" use="optional">
   <xs:simpleType>
    <xs:restriction base="xs:string">
     <xs:minLength value="7"/>
     <xs:maxLength value="16"/>
    </xs:restriction>
   </xs:simpleType>
  </xs:attribute>
 </xs:complexType>
</xs:schema>

Note that this doesn't really give you what you want since the XPath
expression *[@type = 'BridgedEthernet'] will select all element nodes in
your XML document that has an attribute type with the value
'BridgedEthernet'. What you really want is to get all elements that are of
type 'BindType' AND has an attribute type with the value 'BridgedEthernet'.
Unfortunately, you can't select nodes based on XML Schema datatypes in the
current version of XPath but I think this is an upcoming feature for the
next version. The XPath would then probably look something like
*[Datatype='BindType'][@type='BridgedEthernet']
The Schematron Validator from Topologi [1] can validate XML Schemas and
Schematron as well as provide validation results from embedded Schematron
rules like the above example. For more information about Schematron see [2]
and more information about how to extend XML Schemas can be found at [3].

Cheers,
/Eddie

[1] www.topologi.com
[2] http://www.ascc.net/xml/resource/schematron/
[3] http://www.xfront.com/BestPracticesHomepage.html (see Extending XML
Schemas)

Received on Tuesday, 25 September 2001 20:01:04 UTC