【发布时间】:2010-10-27 20:09:20
【问题描述】:
我正在尝试使用 xs:key 和 xs:keyref 定义在 XML 模式上定义一些外键约束。我希望文档的结构按以下方式分层:
<?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 仅在其包含的 parent 范围内是唯一的。
然后有一个引用列表,其中包含对特定父级和子级的外键引用。
我可以根据需要定义键,只需将它们放在正确的元素上:根元素上的 parentKey 约束和父元素上的 childKey 约束。我也可以毫无困难地将 keyref 定义为 parentKey。
在尝试为 childKey 定义 keyref 时会出现问题。我尝试在 childKey 的根元素上定义一个简单的 keyref,但这不起作用,因为我看不到仅选择正确父子树下的子元素的方法。 (至少,Eclipse 验证器总是简单地针对文档中 last 父子树的内容进行验证...)。
然后我尝试定义一个复合键(在 root 上),使用:
- 选择器 = 父级
- 字段 = @parentKey
- field = child/@childKey
如果在父项下定义了多个子项,则会失败。这是基于XSD 1.1 spec 第 3.11.4 节第 3 项的正确行为,其中指出键必须与每个字段定义最多匹配一个节点。
重申一下:如果我强制 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>
【问题讨论】:
-
嗨 Aron,您找到解决此问题的方法了吗?我也遇到了类似的问题。(我无法更改我的 xml)。
-
恐怕不会 - 我们最终转向了非 XML 格式进行数据交换,从而使问题变得毫无意义。