W3C home > Mailing lists > Public > xmlschema-dev@w3.org > January 2013

Re: keyref to a key in a different scope

From: Michael Kay <mike@saxonica.com>
Date: Mon, 14 Jan 2013 14:23:54 +0000
Message-ID: <50F414FA.2070304@saxonica.com>
To: xmlschema-dev@w3.org

On 14/01/2013 13:16, George Cristian Bina wrote:
> Hi all,
>
> I have problems identifying the relevant parts of the XML Schema spec 
> that apply to the following example. 

You're not the only one. This bit of the spec is horrendous. I generally 
advise users against doing this.

First we need to look in 3.11.5 to understand the identity-constraint 
tables that are built. (I'm using the 1.1 spec, though I don't think it 
is materially different).

For each of the two "child" elements, the key named "k" is an eligible 
identity-constraint, and the element therefore has an 
identity-constraint table with a single entry, which (under rule 2 of 
"node table") associates the contraint "k" with a node table which 
itself has a two entries. The node table for the first child is (("a1", 
child[1]/element[1]), ("a2", child[1]/element[2]), and that for the 
second is (("a1", child[2]/element[1]), ("a4", child[2]/element[2]).

For the parent element, "k" is also an eligible identity constraint, 
because the element has a child with an identity-constraint table for 
that constraint. For the parent element. Under rule 1, this would 
include the four entries

("a1", child[1]/element[1]),
("a2", child[1]/element[2]),
("a1", child[2]/element[1]),
("a4", child[2]/element[2])

except that the "provided" clause underneath rule 2 (which we can tell 
by virtue of indentation is supposed to qualify both rules 1 and 2) is 
not satisfied (two entries have the same key but different nodes). My 
reading of the rule about conflicts is that after resolving conflicts, 
the node table is now

("a2", child[1]/element[2]),
("a4", child[2]/element[2])


The next place to look is 3.11.4

We'll now examine whether "parent" is valid given the keyref constraint. 
So E=parent.

Rule 1: the target node set is the two test elements. True.

Rule 2: True.

Rule 3: All the conditions are satisfied, and the key-sequences for the 
two test elements are "a2" and "a1" respectively.

Rule 4: The qualified node set is the same as the target node set (the 
two test elements).

Rule 4.3: I am appalled to see that the spec still contains the totally 
incomprehensible phrase "which is understood as logically prior to this 
clause of this constraint, below". I have never known what that is 
supposed to mean. But let's battle on. What 4.3 tells us is that E is 
valid if E (the parent element) has a "node table" corresponding to "k" 
which contains an entry for every test/@ref value, that is, for "a2" and 
"a1".

If the above interpretation of the conflict resolution is correct, E's 
node table does not have an entry for "a1" (because the value appeared 
more than once) and therefore E is not valid.

Whether this is actually what's going on in Saxon's implementation I 
have no idea. If the spec is impenetrable, so is Saxon's implementation, 
and there isn't a neat one-to-one correspondence between the two. (This 
is partly so that we can produce better diagnostics.) But I think the 
answer is right., and the nature of the error message (More than one 
referenced value found for keyRef {kr} "a1") appears to confirm this.

Michael Kay
Saxonica
> There is a key defined on the "child" element selecting the 
> "element/@id" attribute and a key reference defined on the "parent" 
> element that specifies that "test/@ref" points to "child/element/@id" 
> attributes:
>
> <?xml version="1.0" encoding="UTF-8"?>
> <parent xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>  xsi:noNamespaceSchemaLocation="test.xsd">
>     <child>
>         <element id="a1"/>
>         <element id="a2"/>
>     </child>
>     <child>
>         <element id="a1"/>
>         <element id="a4"/>
>     </child>
>     <test ref="a2"/>
>     <test ref="a1"/>
> </parent>
>
> test.xsd:
>
> <?xml version="1.0" encoding="UTF-8"?>
> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
> elementFormDefault="qualified">
>   <xs:element name="parent">
>     <xs:complexType>
>       <xs:sequence>
>         <xs:element name="child" maxOccurs="unbounded">
>           <xs:complexType>
>             <xs:sequence maxOccurs="unbounded">
>               <xs:element name="element">
>                 <xs:complexType>
>                   <xs:attribute name="id" use="required"/>
>                 </xs:complexType>
>               </xs:element>
>             </xs:sequence>
>           </xs:complexType>
>           <xs:key name="k">
>             <xs:selector xpath="element"/>
>             <xs:field xpath="@id"/>
>           </xs:key>
>         </xs:element>
>         <xs:element name="test" maxOccurs="unbounded">
>           <xs:complexType>
>             <xs:attribute name="ref"/>
>           </xs:complexType>
>         </xs:element>
>       </xs:sequence>
>     </xs:complexType>
>     <xs:keyref name="kr" refer="k">
>       <xs:selector xpath="test"/>
>       <xs:field xpath="@ref"/>
>     </xs:keyref>
>   </xs:element>
> </xs:schema>
>
> Xerces seems to discard all the key defined on "child" elements except 
> the ones defined on the last "child" element, in the example only the 
> "a1" and "a4" values are used when the keyref is checked.
>
> Saxon EE keeps all the key values, each set on its key space (that is 
> each "child" element) and it triggers an error on the reference to a 
> key that is defined in both "child" elements, the reference to "a1".
>
> My feeling is that Xerces is wrong and Saxon is correct but as I 
> mentioned I cannot identify in the specification the relevant sections 
> for this situation.
>
> Here there are the errors reported by Saxon
>
> System ID: /Users/george/Documents/test/validation/instance1.xml
> Main validation file: 
> /Users/george/Documents/test/validation/instance1.xml
> Schema: /Users/george/Documents/test/validation/test.xsd
> Engine name: Saxon-EE 9.4.0.6
> Severity: fatal
> Description: More than one referenced value found for keyRef {kr}
>     "a1"
> Start location: 9:27
>
> System ID: /Users/george/Documents/test/validation/instance1.xml
> Main validation file: 
> /Users/george/Documents/test/validation/instance1.xml
> Schema: /Users/george/Documents/test/validation/test.xsd
> Engine name: Saxon-EE 9.4.0.6
> Severity: fatal
> Description: More than one referenced value found for keyRef {kr}
>     "a1"
> Start location: 10:36
>
> System ID: /Users/george/Documents/test/validation/instance1.xml
> Main validation file: 
> /Users/george/Documents/test/validation/instance1.xml
> Schema: /Users/george/Documents/test/validation/test.xsd
> Engine name: Saxon-EE 9.4.0.6
> Severity: fatal
> Description: More than one referenced value found for keyRef {kr}: "a1"
> Start location: 5:0
>
> and here it is the error reported by Xerces:
>
> System ID: /Users/george/Documents/test/validation/instance1.xml
> Main validation file: 
> /Users/george/Documents/test/validation/instance1.xml
> Schema: /Users/george/Documents/test/validation/test.xsd
> Engine name: Xerces
> Severity: error
> Description: cvc-identity-constraint.4.3: Key 'kr' with value 'a2' not 
> found for identity constraint of element 'parent'.
> Start location: 14:10
> URL: http://www.w3.org/TR/xmlschema-1/#cvc-identity-constraint
>
> Best Regards,
> George
> -- 
> George Cristian Bina
> <oXygen/> XML Editor, Schema Editor and XSLT Editor/Debugger
> http://www.oxygenxml.com
>
>
Received on Monday, 14 January 2013 14:24:23 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Monday, 14 January 2013 14:24:23 GMT