我在根元素上创建了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>
模式,但结构是相同的;这只是我一直在玩的测试模式)
unique
感谢@PetruGardea跟进我的修订。所以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>
引用,谁知道? (显然不是我)
{{1}}
答案 0 :(得分:3)
使用xsd:unique;与密钥不同,它的匹配值是唯一的或零(零或不存在)。
示例:
<?xml version="1.0" encoding="utf-8" ?>
<!-- XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com) -->
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="root">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="uk" maxOccurs="unbounded">
<xsd:complexType>
<xsd:attribute name="name" type="xsd:string"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="fk" maxOccurs="unbounded">
<xsd:complexType>
<xsd:attribute name="name" type="xsd:string"/>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:unique name="uq">
<xsd:selector xpath="uk"/>
<xsd:field xpath="@name"/>
</xsd:unique>
<xsd:keyref name="fk" refer="uq">
<xsd:selector xpath="fk"/>
<xsd:field xpath="@name"/>
</xsd:keyref>
</xsd:element>
</xsd:schema>
示例(有效)XML:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- Sample XML generated by QTAssistant (http://www.paschidev.com) -->
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<uk name="name1"/>
<uk />
<fk/>
<fk name="name1"/>
</root>