Page 1 of 1

xs:key and xs:keyref - invalid instance passes validation

Posted: Thu Jan 26, 2006 4:35 pm
by maltit
Hi,

first of all - Oxygen rocks! Its never been such a pleasure developing XSLT stylesheets. Now I have a little problem:

My schema constrains certain values to match certain other values using xs:key and xs:keyref. Here it is:

<!-- SCHEMA -->
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://foo.bar" xmlns="http://foo.bar" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="rootElement">
<xs:complexType mixed="false">
<xs:sequence>
<xs:element name="someElement">
<xs:complexType mixed="false">
<xs:sequence>
<xs:element name="someElementReferencingAKey" type="xs:integer"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="collectionOfKeyedElements">
<xs:complexType mixed="false">
<xs:sequence>
<xs:element name="element" minOccurs="0" maxOccurs="unbounded">
<xs:complexType mixed="false">
<xs:attribute name="refId" type="xs:integer" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:key name="elementRefId">
<xs:selector xpath="collectionOfKeyedElements/element"/>
<xs:field xpath="@refId"/>
</xs:key>
<xs:keyref name="referenceToElement" refer="elementRefId">
<xs:selector xpath="someElement/someElementReferencingAKey"/>
<xs:field xpath="."/>
</xs:keyref>
</xs:element>
</xs:schema>


No when I validate an obviously invalid (as far as keys go) instance document with Oxygen 7.0, it does not complain but says the doc is valid. Here's the instance:

<!-- INSTANCE DOC -->
<?xml version="1.0" encoding="UTF-8"?>
<rootElement xmlns="http://foo.bar" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://foo.bar schema.xsd">
<someElement>
<someElementReferencingAKey>0</someElementReferencingAKey>
</someElement>
<collectionOfKeyedElements>
<element refId="1"/>
<element refId="2"/>
</collectionOfKeyedElements>
</rootElement>

someElementReferencingAKey should be either 1 or 2, but not 0.

Is there any way to force Oxygen to validate documents obeying such constraints?

Thanks,
Oliver

Posted: Fri Jan 27, 2006 11:16 am
by george
Hi Oliver,

The problem is that both your key and keyref do not match anything from your document so there is nothing that can fail. Whay is that so? Because XPath expressions do not use the default namespace for name tests and when you say for instance someElement/someElementReferencingAKey in the keyref selector that means you are looking for someElement from no namespace and someElementReferencingAKey from no namespace. In your document there are elements with the same local name but they are from the http://foo.bar namespace.
To solve this you need to declare a prefix for the http://foo.bar namespace and use that to qualify the name tests in the XPath expressions. Full working schema below:

Code: Select all


<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://foo.bar" xmlns="http://foo.bar" xmlns:t="http://foo.bar"
xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="rootElement">
<xs:complexType mixed="false">
<xs:sequence>
<xs:element name="someElement">
<xs:complexType mixed="false">
<xs:sequence>
<xs:element name="someElementReferencingAKey" type="xs:integer"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="collectionOfKeyedElements">
<xs:complexType mixed="false">
<xs:sequence>
<xs:element name="element" minOccurs="0" maxOccurs="unbounded">
<xs:complexType mixed="false">
<xs:attribute name="refId" type="xs:integer" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:key name="elementRefId">
<xs:selector xpath="t:collectionOfKeyedElements/t:element"/>
<xs:field xpath="@refId"/>
</xs:key>
<xs:keyref name="referenceToElement" refer="elementRefId">
<xs:selector xpath="t:someElement/t:someElementReferencingAKey"/>
<xs:field xpath="."/>
</xs:keyref>
</xs:element>
</xs:schema>
Best Regards,
George

Posted: Mon Jan 30, 2006 2:59 pm
by maltit
George,

thank you very much for pointing that out. I just didn't realize that, of course, using XPath expressions inside an instance document requires a qualified namespace, just as in my XSLT stylesheets.

regards,
Oliver