co-constraints (RQ-38) LC-193

Dear WG, 

-> Regarding requirements for XML Schema 1.1, 

-> -> Regarding desideratum 2.2.2.1 co-constraints (RQ-38) 


One of the most frequent cases for people who start by writing XML and
then decide to formalize the corresponding XML Schema is to run into
this kind of case 

<object type="a" attribute_a1="foo" attribute_a2="bar"
attribute_ab1="buzz"> 
        <element_a1>some content</element_a1> 
        <element_a2>more content</element_a2> 
        <element_ab1>more content</element_ab1> 
</object> 

<object type="b" attribute_b1="foo" attribute_ab1="bar"> 
        <element_b1>some content</element_b1> 
        <element_ab1>more content</element_ab1> 
</object> 

So the wish-list for RQ-38 should IMHO include the possibility to
formalize the following constraints 

If element 'object' has attribute 'type' and the value of 'type' (in
value space) is x (or if the default value of absent attribute 'type' is
x) then

- only attributes 'attribute_a1', 'attribute_a2' and 'attribute_ab1' are
allowed. 
- Possibly more constraints/facets on the values of these attributes in
this case 
- Only elements 'element_a1', 'element_a2' and 'element_ab1' are allowed

- Possibly more constraints/facets on these values. 

In addition, the attributes should not need be defined global for their
definition be reusable (attribute_ab1 and element_ab1 are common).

One xml schema difficult to write in this respect is the one used by
Apache Tomcat to store its configuration (server.xml).

For example element "Connector" has several forms the discriminant
attribute is 'protocol'. 

<Connector protocol="" more_attributes_here=""
some_are_common_to_all_protocols=""
others_are_specific_to_a_protocol="">

XSD purists will probably argue that the XML is not well designed and
that one (Craig) should have designed like this : 

<Connector-http> 
        <port>80</port> 
</Connector-http> 

<Connector-ajp13> 
        <port>8009</port> 
</Connector-ajp13> 

Etc.. 
Conversely, one could also that XML Schema should not hold back
"expression" deemed natural by "authors". 

It is more or less possible to describe server.xml in schematron or
relax-ng.  
Validation is doable with these validators (or even with custom
XSL/XPath combinations). 
However XSD is often used to support so-called code-assist features in
XML editors. 
These are huge productivity contributors.  However, most of these only
support XML schema.  Only a few support relax-ng and/or schematron.

Another ubiquitous example is the plugin.xml of Eclipse.  
The content of the 'extension' element actually depends on the value of
its 'point' attribute. 
Eclipse folks have an XSD for nearly each extension point but I don't
believe they can write a complete XSD for the plugin.xml document.

I'm conscious of the difficulty of the exercise though. 

If we look at the way a code-assist uses an XSD today, things works like
this : the cursor actually walks though a tree of possible options.  

Each time the user selects an option, it moves to an adjacent node of
the tree and the options are updated accordingly. 
The problem is that the tree of possibilities in XSD 1.0 takes only into
account two entities : element-nodes and attribute nodes, not
leaf-node-values.

So 1.0 has picked the lowest fruit first.  If we accept the idea of
introducing leaf-node-values based criteria, there is actually a hidden
new principle :

The value of a leaf node changes the options of siblings (other atts or
elements of parent node) (as opposed to descendent nodes only today).

In addition, there is the question of the number of acceptable
discriminant leaf nodes.  
When there is only one, there will be no conflict to manage.  Otherwise
things get complicated. 

Example 

<xs:simpleType name="connectorTypes"> 
  <xs:restriction base="xs:string"> 
    <xs:enumeration value="HTTP/1.1"/> 
    <xs:enumeration value="AJP/1.3"/> 
  </xs:restriction> 
</xs:simpleType> 

<xs:element name="Connector"> 
  <xs:attribute name="protocol" use="optional" 
                type="connectorTypes" default="HTTP/1.1"/> 
  <xs:attributeGroup ref="CommonConnectorsAttributes"/> 
  <xs:complexType> 
    <xs:select discriminant="@protocol"> 
      <xs:case value="HTTP/1.1"> 
        <xs:attributeGroup ref="http11SpecificConnectorsAttributes"/> 
      </xs:case> 
      <xs:case value="AJP/1.3"> 
         <xs:attributeGroup ref="ajp13SpecificConnectorsAttributes"/> 
      </xs:case> 
    </xs:select> 
  </xs:complexType> 
</xs:element> 

I might be wrong (fairly new to XSD actually) but I didn't see any way
of doing this today with 1.0.  
(If there is a way, please be kind enough to send me a solution...) 

Just my two cents anyway, thanks for reading. 


Alain Pannetier 

Received on Tuesday, 26 July 2005 13:48:03 UTC