[Improvement] Extend restricted xpath expressions

Dear XML Schema Working Group,

I am studying Computer Science at the Brandenburg University of 
Technology at Cottbus in Germany. During my studies I had some projects 
with XML-Schema. During my current project I discovered that the 
restricted xpath expressions for the <selector> and <field> elements are 
too restricted.

I came to this conclusion because of the follwing problem:

I have a <root> element which can contain a sequence of  <entity> 
elements followed by a set of <reference> elements. Each <entity> is 
identified by a @name attribute and can contain zero or more <property> 
elements. Each <property> is also identified by its @name attribute. A 
<reference> refers to a <property> of a given <entity>.

XML-Document:
<root>
 <entity name="e1">
   <property name="p1"/>
   <property name="p2"/>
 </entity>
 <entity name="e2">
   <property name="p1"/>
   <property name="p3"/>
 </entity>
 <reference entity="e1" property="p1"/>
 <reference entity="e2" property="p2"/>
 <reference entity="e2" property="p3"/>
</root>

XSD-Document:
<xs:schema>
 <xs:element name="root" type="root.type"/>
 <xs:complexType name="root.type">
   <xs:sequence>
     <xs:element ref="entity" minOccurs="0" maxOccurs="unbounded"/>
     <xs:element ref="reference" minOccurs="0" maxOccurs="unbounded"/>
   </xs:sequence>
 </xs:complexType>

 <xs:element name="entity" type="entity.type"/>
 <xs:complexType name="entity.type">
   <xs:sequence>
     <xs:element ref="property" minOccurs="0" maxOccurs="unbounded"/>
   </xs:sequence>
   <xs:attribute name="name" type="xs:string" use="required"/>
 </xs:complexType>

 <xs:element name="property" type="property.type"/>
 <xs:complexType name="property.type">
   <xs:attribute name="name" type="xs:string" use="required"/>
 </xs:complexType>

 <xs:element name="reference" type="reference.type"/>
 <xs:complexType name="reference.type">
   <xs:attribute name="entity" type="xs:string" use="required"/>
   <xs:attribute name="property" type="xs:string" use="required"/>
 </xs:complexType>
</xs:schema>

Now I want to ensure that a <reference> refers to an existing 
<entity>/<property> pair. In other words the 2nd reference of the 
example above should result in an error.

To achieve this I have to define a key which contains the @name of the 
<property> and of the <entity> which encloses the <property>. Since the 
<property> is the element I want to refer to it has to be the selector. 
But according to the fact that the current restricted xpath expression 
just allows the self, attribute, child and descendant axes I am unable 
to solve this problem in a proper way.

The only way for now is to add a redundant @base attribute to the 
<property> that refers to the @name attribute of the enclosing <entity>. 
With the help of this new attribute I can create a key/keyref pair which 
solves my problem.

XML-Document:
<root>
  <entity name="e1">
    <property base="e1" name="p1"/>
    <property base="e1" name="p2"/>
  </entity>
  <entity name="e2">
    <property base="e2" name="p1"/>
    <property base="e2" name="p3"/>
  </entity>
  <reference entity="e1" property="p1"/>
  <reference entity="e2" property="p2"/>
  <reference entity="e2" property="p3"/>
</root>

XSD-Document:
<xs:schema>
  <xs:element name="root" type="root.type">
    <xs:key name="property.key>
      <xs:selector xpath="entity/property"/>
      <xs:field xpath="@base"/>
      <xs:field xpath="@name"/>
    </xs:key>
    <xs:keyref name="property.ref" refer="property.key">
      <xs:selector xpath="reference"/>
      <xs:field xpath="@entity"/>
      <xs:field xpath="@propety"/>
    </xs:keyref>
  </xs:element>
  <xs:complexType name="root.type">
    <xs:sequence>
      <xs:element ref="entity" minOccurs="0" maxOccurs="unbounded"/>
      <xs:element ref="reference" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>

  <xs:element name="entity" type="entity.type">
    <xs:key name="entity.key">
      <xs:selector="."/>
      <xs:field xpath="@name"/>
    </xs:key>
    <xs:keyref name="entity.ref" refer="entity.key">
      <xs:selector="property"/>
      <xs:field xpath="@base"/>
    </xs:keyref>
  </xs:element>
  <xs:complexType name="entity.type">
    <xs:sequence>
      <xs:element ref="property" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
    <xs:attribute name="name" type="xs:string" use="required"/>
  </xs:complexType>

  <xs:element name="property" type="property.type"/>
  <xs:complexType name="property.type">
    <xs:attribute name="base" type="xs:string" use="required"/>
    <xs:attribute name="name" type="xs:string" use="required"/>
  </xs:complexType>

  <xs:element name="reference" type="reference.type"/>
  <xs:complexType name="reference.type">
    <xs:attribute name="entity" type="xs:string" use="required"/>
    <xs:attribute name="property" type="xs:string" use="required"/>
  </xs:complexType>
</xs:schema>

But as you can see this workaround requires a redundant information 
which is already given by the document's structure. Using this solution 
might be ok for small projects, but in bigger ones it requires alot of 
redundant information. According to this the resulting xml documents 
would be needlessly expanded which makes the documents hard to read and 
to write.

For this reason I would recommend to extend the current restricted xpath 
expressions for the <selector> and <field> elements at least with the 
parent axis. To be able to handle some other similiar problems too, it 
would be nice if other axes like the ancestor and sibling axes would 
also be be available.

Regards,
Thomas Grundmann

Received on Monday, 23 February 2009 11:05:30 UTC