Re: How to reference attributes from list items

Hi Eric,

Eric Jain wrote:

>Sorry, another unanswered and recycled question (from comp.text.xml):
>
>Is it possible to create a schema that asserts that the first element
>of a list refers to an attribute? Example:
>
><entry key="103">
>    <list>
>        <item>103</item>
>        <item>101</item>
>        <item>204</item>
>    </list>
></entry>
>
>As a first step, the key attribute can be defined to be a key, no
>problem there:
> 
><xsd:key name="entryKey">
>    <xsd:selector xpath="entry"/>
>    <xsd:field xpath="@key"/>
></xsd:key>
>
>Now I can have *all* items refer to the key attribute of their entry
>(or another one, depending on the scope):
>
><xsd:keyref name="key-ref" refer="entryKey">
>    <xsd:selector xpath="entry/list/item"/>
>    <xsd:field xpath="."/>
></xsd:keyref>
>
>But now how do I limit this restriction to the first element of the
>list? This doesn't work:
> 
><xsd:keyref name="key-ref" refer="entryKey">
>    <xsd:selector xpath="entry/list"/>
>    <xsd:field xpath="item[1]"/>
></xsd:keyref>
>
>Any ideas? Or is this in fact a limitation of W3C Schema? There is
>some mention of 'XPath subset' in http://www.w3.org/TR/xmlschema-1/,
>but I couldn't find any further details. Alternative strategies?
>
Unfortunately you can't do this W3C XML Schema 1.0 since it only allows 
for a subset of XPath in it's identity constaints (predicates not 
included). Identity constraints and co-occurence constraints is on the 
table for a rework in coming versions of the language. For now you have 
two options:

1) Move to a schema language that supports this constraint (I think the 
only option is Schematron [1] but I'm not 100% sure)
2) Embedd a Schematron rule in your W3C XML Schema to check the 
constraint [2]. Here's an example of how to do this:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
elementFormDefault="qualified">
  <xs:element name="entry">
    <xs:annotation>
      <xs:appinfo>
        <!-- Embedded Schematron rule that asserts that the first item 
element in the list match the key attribute -->
        <sch:pattern name="Check first item" 
xmlns:sch="http://www.ascc.net/xml/schematron">
          <sch:rule context="entry">
            <sch:assert test="@key = list/item[1]">The value of the key 
attribute must match the first item element in the list.</sch:assert>
          </sch:rule>
        </sch:pattern>
      </xs:appinfo>
    </xs:annotation>
    <xs:complexType>
      <xs:sequence>
        <xs:element name="list">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="item" type="xs:string" 
maxOccurs="unbounded"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
      <xs:attribute name="key" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
</xs:schema>


Cheers,
/Eddie

[1] http://www.ascc.net/xml/resource/schematron/
[2] http://www.topologi.com/public/Schtrn_XSD/Paper.html

Received on Sunday, 8 September 2002 20:53:22 UTC