RE: key/keyref problem

Hi Eric,

> This is a point I find most confusing in the spec.

Yes, I agree that this point is quite confusing.

>
> The rec [1] says that:
>
> If the {identity-constraint category} is keyref, then for
> each member of
> the ·qualified node set· (call this the keyref member), there
> must be a
> ·node table· associated with the {referenced key} in the
> [identity-constraint table] of the element information item (see
> Identity-constraint Table (§3.11.5), which must be understood as
> logically prior to this clause of this constraint, below) and
> there must
> be an entry in that table whose ·key-sequence· is equal to the keyref
> member's ·key-sequence· member for member, as defined by Equal in [XML
> Schemas: Datatypes].
>
> [1]
> http://www.w3.org/TR/2001/REC-xmlschema-1-20010502/#section-Id
> entity-constraint-Definition-Information-Set-Contributions
>
> I am probably wrong, but I read this as implying a need that
> the key and
> keyref tables belong to the same element.
>

I can see how you'd read it that way.  But the node table for that element
(the one that is the scope of the keyref) contains entries for all of its
descendent's keys also.  In section 3.11.5:

"A ·node table· with one entry for every ·key-sequence· (call it k) and node
(call it n) such that one of the following must be true:
1 There is an entry in one of the ·node tables· associated with the
[definition] in an Identity-constraint Binding information item in at least
one of the [identity-constraint table]s of the element information item
[children] of the element information item whose ·key-sequence· is k and
whose node is n;
2 n appears with ·key-sequence· k in the ·qualified node set· for the
[definition]. "

The important word is "children."  In other words, the node table entries
are propagated upward to the parent elements.


> Furthermore, I would also think that allowing scoping element
> of the key
> or unique definition to be a child of the scoping element of
> the keyref
> still more confusing.
>
> If I understand what you mean correctly, it's allowing cases such as:
>
> <root>
>  <sub>
>    <key id="1"/>
>    <key id="2"/>
>  </sub>
>  <sub>
>    <key id="2"/>
>    <key id="3"/>
>  </sub>
>  <keyref ref="2"/>
> </root>
>
> .../...
>
> <xs:element name="root">
>
>   <xs:element name="sub">
>    .../...
>    <xs:key name="key">
>     <xs:selector xpath="key"/>
>     <xs:field xpath="@id"/>
>    </xs:key>
>   </xs:element>
>
>   <xs:keyref name="keyref" refer="key">
>    <xs:selector xpath="keyref"/>
>    <xs:field xpath="@ref"/>
>   </xs:key>
>
> </xs:element>
>
> where one cannot determine which key is referred by a keyref.
>

That schema is fine.  The instance is not valid because, as you point out,
the keyref does not reference a single key sequence. If your instance had
contained <keyref ref="1"/> it _would_ be valid. This is also described in
section 3.11.5, where it describes conflict resolution for the node table:

"Potential conflicts are resolved by not including any conflicting entries
which would have owed their inclusion to clause 1 above. Note that if all
the conflicting entries arose under clause 1 above, this means no entry at
all will appear for the offending ·key-sequence·. "


> This is also troubling to see that the scope of a key is
> wider than the
> element in which it is defined and I would have found it less
> confusing
> if it would have been the scoping element of the keyref that
> could have
> been a child of the scoping element of the key or unique.

It may help to think of a relational database analogy, where keys are
primary keys and keyrefs are foreign keys.  A primary key is defined on a
particular table.  Foreign keys can then reference that primary key from
other tables in the database (a broader scope).


Does that make more sense?

Priscilla Walmsley
Vitria Technology

Received on Monday, 2 July 2001 21:31:43 UTC