Я пытаюсь определить некоторые ограничения внешнего ключа для схемы 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. Я попытался определить простой keyref в корневом элементе childKey, но это не работает, поскольку я не вижу способа выбрать только дочерние элементы под соответствующим родительским поддеревом. (Валидатор Eclipse, по крайней мере, всегда просто проверяет содержимое последнего родительского поддерева в документе...).
Затем я попытался определить составной ключ (в корне), используя:
- selector = parent
- поле = @parentKey
- field = child/@childKey
Это не удается, если для родителя установлено более одного дочернего элемента. Это правильное поведение, основанное на XSD 1.1 spec, раздел 3.11.4, пункт 3, в котором говорится, что ключ должен соответствовать не более одного node для определения поля.
Просто повторю: если я заставляю childKeys быть глобально уникальными, это легко реализовать; сложность связана с привязкой локально уникальных childKeys.
У всех мастеров XSD есть идея?
Для справки, вот пример XSD, с провалом childKey keyref:
<?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>