Re: <key> and <keyref>

Hi Hamid,

> May this schema be valid? Can a key reference another one and in the
> same time being referenced by the second key? May be that it is not
> so interesting when the key is just an attribute of type string but
> the case is different when the key is composed of different
> attributes and elements.

Yes, a particular attribute can be both a method of indexing an
element and a method of referring to other elements (though this could
only give you a one-to-one mapping between elements, and if you have a
one-to-one mapping you may as well use nesting rather than references
to indicate the relationship between the elements).

However, I don't think that you're defining your keys in the right
place to make it work. Take the example:

<element name='A'>
 <complexType>
  <attribute name='a' type='string'/>
 </complexType>

 <key name='KEYa'>
  <selector xpath='.//A'/> <!-- to select the element A -->
  <field xpath='@a'/> <!-- to select the attribute a -->
 </key>
 ...
</element>

This says that within any A element in the instance document, all its
descendant A elements must have a attributes with unique values. The
content model shows that A elements are empty, so I don't think you've
got a recursive definition here, so I think that the key identity
constraint is in the wrong place. If you have a structure like:

<doc>
  <A a="abc" />
  <A a="def" />
  <B b="abc" />
  <B b="def" />
</doc>

then you need to place the key identity constraint on the declaration
for the doc element, so that all the A elements that you're interested
in are held within it. Then you can use:

<xs:element name="doc">
  <xs:complexType>
    <xs:sequence>
      <xs:element ref="A" maxOccurs="unbounded" />
      <xs:element ref="B" maxOccurs="unbounded" />
    </xs:sequence>
  </xs:complexType>

  <xs:key name="KEYa">
    <xs:selector xpath="A" /><!-- to select all A elements -->
    <xs:field xpath="@a" /><!-- to index by their a attribute -->
  </xs:key>

  <xs:key name="KEYb">
    <xs:selector xpath="B" /><!-- to select all B elements -->
    <xs:field xpath="@b" /><!-- to index by their b attribute -->
  </xs:key>
</xs:element>

The key reference identity constraint must defined be on an element
declaration for an element that (a) contains all the elements that you
want to reference and (b) contains all the elements that hold
references. Again, this is the doc element, so the element declaration
for the doc element needs to contain the xs:keyref elements as well:

<xs:element name="doc">
  ...
  <xs:keyref name="RefToKEYb" refer="KEYb">
    <xs:selector xpath="A" /><!-- to select all A elements -->
    <xs:field xpath="@a" /><!-- to refer using their a attribute -->
  </xs:keyref>

  <xs:keyref name="RefToKEYa" refer="KEYa">
    <xs:selector xpath="B" /><!-- to select all B elements -->
    <xs:field xpath="@b" /><!-- to refer using their b attribute -->
  </xs:keyref>
</xs:element>

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/

Received on Monday, 5 November 2001 05:50:55 UTC