Enforcing XSD key and keyref constraints is not working well with a recursive schema definition

327 views Asked by At

I am trying to enforce key and reference constraints in my custom XML format by using XSD's <xs:key> and <xs:keyref> elements. It is not working as I would like it to.

First an example instance of my XML format:

<room xmlns="http://example.com">
  <box>
    <item name="x" uses="y" />
    <item name="y" uses="z" />
    <item name="z" />
    <box>
      <item name="p" uses="q" />
      <item name="q" uses="r" />
      <item name="r" />
      <box>
      </box>
    </box>
  </box>
</room>

This datastructure describes a "room" with a single "box" in it. A box can contain items and other boxes. A box can also be empty. Items in a box have to have distinct names (but can share a name with items in other boxes), and can only "use" other items that are in the same box.

I am trying to keep the integrity of the "uses" graph by using key/keyrefs on the appropriate attributes. However, when I use the Xerces 2 validator on this XML using the schema below I get the following error:

[Error] file:///example.xml:13:11: cvc-identity-constraint.4.3: Key 'ItemKeyRef' with value 'q' not found for identity constraint of element 'box'.
[Error] file:///example.xml:14:9: cvc-identity-constraint.4.3: Key 'ItemKeyRef' with value 'y' not found for identity constraint of element 'box'.

Schema:

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

  <xs:element name="room" type="example:Room" />

  <xs:complexType name="Room">
    <xs:all>
      <xs:element ref="example:box" />
    </xs:all>
  </xs:complexType>

  <xs:element name="box" type="example:Box">
    <xs:keyref name="ItemKeyRef" refer="example:ItemKey">
      <xs:selector xpath="./example:item" />
      <xs:field xpath="@uses" />
    </xs:keyref>
    <xs:key name="ItemKey">
      <xs:selector xpath="./example:item" />
      <xs:field xpath="@name" />
    </xs:key>
  </xs:element>

  <xs:complexType name="Box">
    <xs:choice minOccurs="0" maxOccurs="unbounded">
      <xs:element name="item" type="example:Item" />
      <xs:element ref="example:box" />
    </xs:choice>
  </xs:complexType>

  <xs:complexType name="Item">
    <xs:attribute name="name" type="xs:string" use="required" />
    <xs:attribute name="uses" type="xs:string" />
  </xs:complexType>
</xs:schema>

I feel like I am doing something very wrong. Why am I getting this error? Shouldn't this validate?

1

There are 1 answers

0
pancake On

I've found out that the Xerces2 Java Parser 2.11.0 that I used contains some bugs when using recursive element definitions and key/keyrefs. When I tried to validate the above XML using oXygen XML Developer, it succeeded, which leads me to believe the bug report at Apache's issue tracker is accurate.