pjm
pjm

Reputation: 315

keyref in xsd not working

Below is a simplified version of my xsd and xml. I am trying to check that each OrderedPart@rPartId has a valid match in Part@PartId.

All tools I have tried tell me this XML is valid against this xsd. But second Order should give error as 67 is not a valid Part@PartId.

XSD

<?xml version="1.0" encoding="UTF-8"?>

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://localhost" xmlns="http://localhost" targetNamespace="http://localhost" elementFormDefault="qualified" attributeFormDefault="unqualified" >

    <xs:element name="root">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="Order" type="OrderType" maxOccurs="unbounded"/>
            <xs:element name="Parts" type="PartType"/>
        </xs:sequence>
    </xs:complexType>

    <xs:keyref name="dummy" refer="pNumKey">
        <xs:selector xpath="tns:OrderedPart" />
        <xs:field xpath="@rPartId"/>
    </xs:keyref>

    <xs:key name="pNumKey">
        <xs:selector xpath="tns:Part"/>
        <xs:field xpath="@PartId"/>
    </xs:key>
</xs:element>

<xs:complexType name="OrderType">
    <xs:sequence>
      <xs:element name="OrderedPart" maxOccurs="unbounded">
          <xs:complexType>
              <xs:attribute name="rPartId" type="xs:integer"/>
          </xs:complexType>
      </xs:element>
  </xs:sequence>
</xs:complexType>

<xs:complexType name="PartType">
    <xs:sequence>
      <xs:element name="Part" maxOccurs="unbounded">
          <xs:complexType>
              <xs:attribute name="PartId" type="xs:integer"/>
          </xs:complexType>
      </xs:element>
  </xs:sequence>
</xs:complexType>
</xs:schema>

and XML:

<?xml version="1.0" encoding="UTF-8" ?>

<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:noNamespaceSchemaLocation="KeyRefs.xsd"  xmlns="http://localhost" >
<Order>
    <OrderedPart rPartId="1"/>
</Order>
<Order>
    <OrderedPart rPartId="67"/> <!-- validation should give error -->
</Order>
<Parts>
    <Part PartId="1"/>
</Parts>
</root>

Suspect its something to do with the xPaths and/or namespaces in selectors. Following input from other posts on this site I have played with the namespace combinations but cannot get this to work.

Any advice welcome.

(updates as OP seem to lose some of the XSD)

Upvotes: 1

Views: 1350

Answers (1)

sergioFC
sergioFC

Reputation: 6016

The main problem of your XSD is that you are not using selectors properly. Selectors are relative to the element they belong to as it is said in XSD specs:

{selector} specifies a restricted XPath ([XPath]) expression relative to instances of the element being declared.

For this reason you need to change your xpath selectors to tns:Order/tns:OrderedPart and tns:Parts/tns:Part in order to select the correct elements.

In addition, you are using PartId attribute as a key, however it is defined as an optional attribute. Usually this is not a desired behaviour as it is an error if the key is not present, so you can use use="required" in the attribute.

Upvotes: 2

Related Questions