Я пытаюсь определить некоторые ограничения внешнего ключа в схеме XML, используя определения xs: key и xs: keyref. Я хочу, чтобы структура документа была иерархической следующим образом:
<?xml version="1.0" encoding="UTF-8"?>
<tns:root xmlns:tns="http://www.example.org/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.org/ SampleSchema.xsd ">
<parent parentKey="parent1">
<child childKey="child1"/>
<child childKey="child2"/>
</parent>
<parent parentKey="parent2">
<child childKey="child1"/>
<child childKey="child2"/>
</parent>
<referrer parentRef="parent1" childRef="child2"/>
</tns:root>
У каждого родителя есть (глобально) уникальный ключ, определенный parentKey. Каждый дочерний элемент имеет ключ, определенный childKey, , но childKey уникален только в пределах области действия содержащего его родителя .
Затем появляется список ссылок с ссылками на внешние ключи для конкретного родителя и потомка.
Я могу определять ключи так, как хочу, просто помещая их в правильный элемент: ограничение parentKey для корневого элемента и ограничение childKey для родительского элемента. Я также могу без труда определить keyref для parentKey.
Проблемы возникают при попытке определить keyref для childKey. Я попытался определить простую ключевую ссылку в корневом элементе для childKey, но это не сработало, поскольку я не вижу способа выбрать только дочерние элементы в соответствующем родительском поддереве. (Валидатор Eclipse, по крайней мере, всегда просто проверяет содержимое родительского поддерева last в документе ...).
Затем я попытался определить составной ключ (для root) с помощью:
- селектор = родительский
- field = @ parentKey
- field = child / @ childKey
Сбой, если под родителем определено более одного потомка. Это правильное поведение, основанное на спецификации XSD 1.1 , раздел 3.11.4, пункт 3, в которой говорится, что ключ должен соответствовать не более одного узла на определение поля.
Просто повторюсь: если я заставлю childKeys быть глобально уникальными, это легко реализовать; Трудность заключается в том, чтобы сослаться на локально уникальных childKeys.
У каких-нибудь мастеров XSD есть идея?
Для справки приведен пример XSD с закомментированным ошибочным ключом childKey:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/" xmlns:tns="http://www.example.org/" elementFormDefault="unqualified">
<element name="root">
<complexType>
<sequence>
<element name="parent" maxOccurs="unbounded" minOccurs="1">
<complexType>
<sequence>
<element name="child" maxOccurs="unbounded" minOccurs="1">
<complexType>
<attribute name="childKey" type="string" use="required"/>
</complexType>
</element>
</sequence>
<attribute name="parentKey" type="string" use="required"/>
</complexType>
<key name="childKeyDef">
<selector xpath="child"/>
<field xpath="@childKey"/>
</key>
</element>
<element name="referrer" maxOccurs="unbounded" minOccurs="1">
<complexType>
<attribute name="parentRef" type="string"/>
<attribute name="childRef" type="string"/>
</complexType>
</element>
</sequence>
</complexType>
<key name="parentKeyDef">
<selector xpath="parent"/>
<field xpath="@parentKey"/>
</key>
<keyref name="parentKeyRef" refer="tns:parentKeyDef">
<selector xpath="referrers"/>
<field xpath="@parentRef"/>
</keyref>
<!-- <keyref name="childKeyRef" refer="tns:childKeyDef">-->
<!-- <selector xpath="referrers"/>-->
<!-- <field xpath="@childRef"/>-->
<!-- </keyref>-->
</element>
</schema>