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

Having trouble installing Oxygen? Got a bug to report? Post it all here.
maltit
Posts: 7
Joined: Thu Jan 26, 2006 4:26 pm

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

Post 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
george
Site Admin
Posts: 2095
Joined: Thu Jan 09, 2003 2:58 pm

Post 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
maltit
Posts: 7
Joined: Thu Jan 26, 2006 4:26 pm

Post 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
Post Reply