XML, XSD xs:keyref в определении рекурсивного сложного типа
У меня есть некоторые данные XML со списком разрешенных типов вверху и рекурсивным списком типов объектов и подобъектов, которые ссылаются на разрешенные типы:
<?xml version="1.0" encoding="UTF-8"?>
<ROOT xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="KEYREF_TEST.xsd">
<ALLOWED_SHAPE_TYPES>
<SHAPE_TYPE>Circle</SHAPE_TYPE>
<SHAPE_TYPE>Triangle</SHAPE_TYPE>
<SHAPE_TYPE>Square</SHAPE_TYPE>
</ALLOWED_SHAPE_TYPES>
<SHAPES>
<SHAPE>
<TYPE>Triangle</TYPE>
<SUB_SHAPES>
<SHAPE>
<TYPE>Circle</TYPE>
<SUB_SHAPES/>
</SHAPE>
<SHAPE>
<TYPE>Square</TYPE>
<SUB_SHAPES>
<SHAPE>
<TYPE>Triangle</TYPE>
<SUB_SHAPES/>
</SHAPE>
</SUB_SHAPES>
</SHAPE>
</SUB_SHAPES>
</SHAPE>
<SHAPE>
<TYPE>Square</TYPE>
<SUB_SHAPES/>
</SHAPE>
</SHAPES>
</ROOT>
Я определил схему, которая проверяет этот документ следующим образом:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="ROOT">
<xs:complexType>
<xs:sequence>
<xs:element name="ALLOWED_SHAPE_TYPES">
<xs:complexType>
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="SHAPE_TYPE" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="SHAPES" type="shape-list-type"/>
</xs:sequence>
</xs:complexType>
<xs:unique name="SHAPE_TYPE_UK">
<xs:selector xpath="ALLOWED_SHAPE_TYPES/SHAPE_TYPE"/>
<xs:field xpath="."/>
</xs:unique>
</xs:element>
<xs:complexType name="shape-list-type">
<xs:sequence>
<xs:element name="SHAPE" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="TYPE" type="xs:string">
<xs:keyref name="SHAPE_TYPE_FK" refer="SHAPE_TYPE_UK">
<xs:selector xpath="."></xs:selector>
<xs:field xpath="."></xs:field>
</xs:keyref>
</xs:element>
<xs:element name="SUB_SHAPES" type="shape-list-type"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:schema>
При проверке в oXygen 13.2 я получаю следующую ошибку:
System ID: C:\pvcswork\CodeSource\XMLSchema\KEYREF_DATA.xml
Main validation file: C:\pvcswork\CodeSource\XMLSchema\KEYREF_DATA.xml
Schema: C:\pvcswork\CodeSource\XMLSchema\KEYREF_TEST.xsd
Engine name: Xerces
Severity: error
Description: Identity Constraint error: identity constraint "KeyRef@1df2ead" has a keyref which refers to a key or unique that is out of scope.
Start location: 10:28
Я полагаю, что это связано с тем, что xs:keyref является потомком определения xs:complexType, которое не является подэлементом элемента xs:, где определено xs:unique.
Я мог бы переместить xs:keyref в определение ROOT и нацелить элементы TYPE на XPath, но синтаксис // недопустим, поэтому я потерял бы рекурсию и должен был бы определить новый xs:keyref для каждого уровня вложенности. ** ОБНОВЛЕНИЕ - // разрешено, когда в начале XPath стоит точка! **
Есть ли решение, которое я пропустил (все еще используя XSD)? Заранее спасибо..
1 ответ
XSD ниже будет моим решением вашей проблемы. Я в основном исправил некоторые селекторы и поставил их на одном уровне.
XSD:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="ROOT">
<xs:complexType>
<xs:sequence>
<xs:element name="ALLOWED_SHAPE_TYPES">
<xs:complexType>
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="SHAPE_TYPE" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="SHAPES" type="shape-list-type"/>
</xs:sequence>
</xs:complexType>
<xs:unique name="SHAPE_TYPE_UK">
<xs:selector xpath="ALLOWED_SHAPE_TYPES/SHAPE_TYPE"/>
<xs:field xpath="."/>
</xs:unique>
<xs:keyref name="SHAPE_TYPE_FK" refer="SHAPE_TYPE_UK">
<xs:selector xpath=".//SHAPE/TYPE"></xs:selector>
<xs:field xpath="."></xs:field>
</xs:keyref>
</xs:element>
<xs:complexType name="shape-list-type">
<xs:sequence>
<xs:element name="SHAPE" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="TYPE" type="xs:string"/>
<xs:element name="SUB_SHAPES" type="shape-list-type"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:schema>