Я создал key
/keyref
для корневого элемента, чтобы создать уникальность для всего документа на основе указанного элемента.
Следовательно, через .//foo/@name
каждое вхождение @name
во всех экземплярах foo
должно быть уникальным; аналогично для .//bar/@name
. Кажется, это работает нормально. На них ссылаются .//foo-ref/@name-ref
и .//bar-ref/@name-ref
соответственно, также определенные в корневом узле.
Однако я понял, что невозможно создать необязательный ключ, и это создает некоторую проблему. Семантически, по характеру соответствующих документов ключ не требуется для каждого экземпляра foo
или bar
. Экземпляры foo-ref/@name-ref
, очевидно, должны быть нацелены на существующий foo/@name
, но семантически недопустимо, чтобы foo
был без @name
.
Есть ли обходной путь для этого? Мне не нравится идея о том, что потребители должны определять ключ для каждого отдельного элемента, когда разумно, что они нужны лишь немногим.
Вот пример схемы (конечно, я не развертываю какую-то схему foobar
, но структура идентична; это всего лишь тестовая схема, с которой я играл)
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="ref">
<xs:attribute name="name-ref" type="xs:string" use="required" />
</xs:complexType>
<xs:complexType name="obj">
<xs:attribute name="name" type="xs:string" use="optional" />
</xs:complexType>
<xs:complexType name="foo">
<xs:complexContent>
<xs:extension base="obj">
<xs:sequence>
<xs:choice maxOccurs="unbounded">
<xs:element name="foo" type="foo" />
<xs:element name="bar" type="bar" />
<xs:element name="foo-ref" type="foo-ref" />
<xs:element name="bar-ref" type="bar-ref" />
</xs:choice>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="foo-ref">
<xs:complexContent>
<xs:extension base="ref" />
</xs:complexContent>
</xs:complexType>
<xs:complexType name="bar">
<xs:complexContent>
<xs:extension base="obj">
<xs:sequence>
<xs:choice maxOccurs="unbounded">
<xs:element name="bar" type="bar" />
<xs:element name="qux" type="qux" />
<xs:element name="bar-ref" type="bar-ref" />
</xs:choice>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="bar-ref">
<xs:complexContent>
<xs:extension base="ref" />
</xs:complexContent>
</xs:complexType>
<xs:complexType name="qux">
<xs:simpleContent>
<xs:extension base="xs:string" />
</xs:simpleContent>
</xs:complexType>
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="foo" type="foo" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:key name="foo">
<xs:selector xpath=".//foo" />
<xs:field xpath="@name" />
</xs:key>
<xs:key name="bar">
<xs:selector xpath=".//bar" />
<xs:field xpath="@name" />
</xs:key>
<xs:keyref name="foo-ref" refer="foo">
<xs:selector xpath=".//foo-ref" />
<xs:field xpath="@name-ref" />
</xs:keyref>
<xs:keyref name="bar-ref" refer="bar">
<xs:selector xpath=".//bar-ref" />
<xs:field xpath="@name-ref" />
</xs:keyref>
</xs:element>
</xs:schema>
Приложение
Просто следите за моими изменениями благодаря @PetruGardea. Итак, на unique
может ссылаться keyref
, кто знал? (очевидно, не я)
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="foo" type="foo" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:keyref name="foo-ref" refer="foo">
<xs:selector xpath=".//foo-ref" />
<xs:field xpath="@name-ref" />
</xs:keyref>
<xs:keyref name="bar-ref" refer="bar">
<xs:selector xpath=".//bar-ref" />
<xs:field xpath="@name-ref" />
</xs:keyref>
<!--
the use of xs:unique here, in lieu of xs:key allows for
nullable "keys", retaining referential integrity with the
above defined keyrefs. awesome possum.
-->
<xs:unique name="foo">
<xs:selector xpath=".//foo" />
<xs:field xpath="@name" />
</xs:unique>
<xs:unique name="bar">
<xs:selector xpath=".//bar" />
<xs:field xpath="@name" />
</xs:unique>
</xs:element>
unique
не поддерживает ссылочную целостность, не так ли? Могу ли я ссылаться наunique
черезkeyref
? 07.04.2013