指定された要素に基づいてドキュメント全体の一意性を作成するために、ルート要素にkey
/を作成しました。keyref
したがって、のすべてのインスタンスで.//foo/@name
発生するすべての viaは一意である必要があります。同様に。これはうまく機能しているようです。これらはそれぞれおよびによって参照され、ルート ノードでも定義されます。@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>