Ограничение ссылочной целостности схемы XML - PullRequest
0 голосов
/ 27 сентября 2019

Я пытаюсь обеспечить ссылочную целостность документа XML.

Вот документ:

<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:noNamespaceSchemaLocation="so.xsd">

   <enumeration name="State" type="byte">
      <literal name="NONE" />
      <literal name="NOMINAL" />
      <literal name="OUT_OF_ORDER" />
   </enumeration>

   <struct name="Speed">
      <field name="valid"    type="boolean" />
      <field name="accuracy" type="double" />
      <field name="value"    type="double" />
   </struct>

   <interface name="IStatus">
      <event name="setStatus">
         <field name="etat"  type="enum"   userTypeName="State" />
         <field name="speed" type="struct" userTypeName="Speed" />
      </event>
   </interface>

</root>

А вот его схема:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" attributeFormDefault="unqualified" elementFormDefault="qualified">

   <xs:simpleType name="enumType">
      <xs:restriction base="xs:string">
         <xs:enumeration value="boolean" />
         <xs:enumeration value="byte" />
         <xs:enumeration value="short" />
         <xs:enumeration value="ushort" />
         <xs:enumeration value="int" />
         <xs:enumeration value="uint" />
      </xs:restriction>
   </xs:simpleType>

   <xs:complexType name="literalType">
      <xs:attribute type="xs:string" name="name" use="required" />
   </xs:complexType>

   <xs:complexType name="enumerationType">
      <xs:sequence>
         <xs:element type="literalType" name="literal" maxOccurs="unbounded" minOccurs="1" />
      </xs:sequence>
      <xs:attribute type="xs:string" name="name" use="required" />
      <xs:attribute type="enumType"  name="type" use="optional" default="byte"/>
   </xs:complexType>

   <xs:complexType name="structType">
      <xs:sequence>
         <xs:element type="fieldType" name="field" maxOccurs="unbounded" minOccurs="1" />
      </xs:sequence>
      <xs:attribute type="xs:string" name="name" use="required" />
   </xs:complexType>

   <xs:simpleType name="fieldtypeType">
      <xs:restriction base="xs:string">
         <xs:enumeration value="boolean" />
         <xs:enumeration value="byte" />
         <xs:enumeration value="short" />
         <xs:enumeration value="ushort" />
         <xs:enumeration value="int" />
         <xs:enumeration value="uint" />
         <xs:enumeration value="long" />
         <xs:enumeration value="ulong" />
         <xs:enumeration value="float" />
         <xs:enumeration value="double" />
         <xs:enumeration value="string" />
         <xs:enumeration value="enum" />
         <xs:enumeration value="struct" />
      </xs:restriction>
   </xs:simpleType>

   <xs:complexType name="fieldType">
      <xs:simpleContent>
         <xs:extension base="xs:string">
            <xs:attribute type="xs:string"     name="name"         use="required" />
            <xs:attribute type="fieldtypeType" name="type"         use="required" />
            <xs:attribute type="xs:string"     name="userTypeName" use="optional" />
         </xs:extension>
      </xs:simpleContent>
   </xs:complexType>

   <xs:complexType name="eventType">
      <xs:sequence>
         <xs:element type="fieldType" name="field" maxOccurs="unbounded" minOccurs="0" />
      </xs:sequence>
      <xs:attribute type="xs:string" name="name" use="required" />
   </xs:complexType>

   <xs:complexType name="interfaceType">
      <xs:sequence>
         <xs:element type="eventType" name="event" maxOccurs="unbounded" minOccurs="0" />
      </xs:sequence>
      <xs:attribute type="xs:string" name="name" use="required" />
   </xs:complexType>

   <xs:complexType name="rootType">
      <xs:sequence>
         <xs:element type="enumerationType" name="enumeration" minOccurs="0" maxOccurs="unbounded" />
         <xs:element type="structType"      name="struct"      minOccurs="0" maxOccurs="unbounded" />
         <xs:element type="interfaceType"   name="interface"   minOccurs="1" maxOccurs="unbounded" />
      </xs:sequence>
   </xs:complexType>

   <xs:element name="root" type="rootType">

      <xs:unique name="type-name">
         <xs:selector xpath=".//enumeration|.//struct"/>
         <xs:field xpath="./@name"/>
      </xs:unique>

      <xs:keyref name="enum-has-been-declared" refer="type-name">
         <xs:selector xpath=".//field[type='enum']"/>
         <xs:field xpath="./@userTypeName"/>
      </xs:keyref>

      <xs:keyref name="struct-has-been-declared" refer="type-name">
         <xs:selector xpath=".//field[type='struct']"/>
         <xs:field xpath="./@userTypeName"/>
      </xs:keyref>

   </xs:element>

</xs:schema>

Синтаксис XPATH, который я пробовал, неверен, поскольку поддерживается только подмножество для XML-схемы:

<xs:keyref name="enum-has-been-declared" refer="type-name">
   <xs:selector xpath=".//field[type='enum']"/>
   <xs:field xpath="./@userTypeName"/>
</xs:keyref>

Как выразить эту ссылкуцелостность

...