我试图使用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>A每个父级都有一个(全局的)唯一键,由parentKey定义。每个子节点都有由childKey定义的密钥,但是childKey仅在其包含的父级的范围内是唯一的。
然后有一个具有外键引用的引用特定父和子引用的引用的引用列表。
我可以根据需要定义键,只需将它们放在正确的元素上:根元素上的parentKey约束和父元素上的childKey约束。我也可以毫不费力地将keyref定义为parentKey。
当试图将keyref定义为childKey时会出现问题。我尝试在根元素上为childKey定义一个简单的keyref,但是这不起作用,因为我看不出只选择正确的父子树下的子元素的方法。(至少Eclipse验证器总是简单地针对文档中最后一个父树的内容进行验证.)。
然后,我尝试定义一个复合键(在root上),使用:
如果在父级下定义了多个子级,则此操作将失败。这是基于XSD 1.1规范第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>发布于 2009-05-21 13:47:36
你说孩子的父母怎么样?即使有许多子键,也只会有一个父键,并且组合(父、子)将创建一个全局唯一的键,尽管子键仅在其父键中是唯一的:
<key name="childKeyDef">
<selector xpath="child"/>
<field xpath="@childKey"/>
<field xpath="../@parentKey"/>
</key>这在xmllint中不起作用,尽管规范似乎没有显式地不允许在字段中这样做--仅用于选择器:3.11.4,(2)表示选择器不能是祖先(只能是上下文节点或后代)。
啊,这是棺材的钉子(看看具体的语法):允许的XPath表达式非常有限,只是不包括“.”http://www.w3.org/TR/xmlschema-1/#c-fields-xpaths
所以,对不起,这没有回答你的问题,但也许它会给你一些想法。
发布于 2009-05-22 08:38:12
一个丑陋的解决方案是更改XML格式,以便在每个子程序中都包含parentKey,如下所示:
<parent>
<child parentKey="parent1" childKey="child1"/>
<child parentKey="parent1" childKey="child2"/>
</parent>我认为您的情况是非常合理的,我希望有一种方法来做到这一点--为什么不试试xml-dev邮件列表呢?据我所知,它变得很嘈杂,但是xml的一些创建者仍然在那里徘徊。
发布于 2009-09-01 15:53:38
我有一个类似的问题:具有多个字段的XML键
我决定,对我来说最好的方法是重新排序XML,以便允许由本地来确定范围,而不是用两个字段强制执行密钥。
在您的场景中,如果您在父级中移动引用器,这将允许将范围设置为引用适当的子元素。然后,您将让referrer元素将外部范围引用到它需要引用的元素。
要确定这是否是一个可接受的解决方案有点困难,因为您的问题似乎有点抽象。在我的问题中,在我的问题中,我处理的是问题、答案和用户的回答。我最初试图验证用户的响应是否实际上是一个有效的答案;我的第一种方法涉及您正在使用的相同的技术。我的最后一个解决方案是将响应移到问题的内部,然后引用用户。
我以前的XML:
<?xml version="1.0" encoding="utf-8"?>
<survey>
<user id="bob">
<response questionIdRef="q101">yes</response>
<response questionIdRef="q102">white</response>
</user>
<user id="jane">
<response questionIdRef="q101">no</response>
<response questionIdRef="q102">blue</response>
</user>
<question id="q101">
<text>Do you like the color red?</text>
<answer>yes</answer>
<answer>no</answer>
</question>
<question id="q102">
<text>What is your favorite color?</text>
<answer>red</answer>
<answer>blue</answer>
<answer>white</answer>
<answer>yellow</answer>
</question>
</survey>我的XML之后:
<?xml version="1.0" encoding="utf-8"?>
<survey>
<user id="bob" />
<user id="jane" />
<question id="q101">
<text>Do you like the color red?</text>
<answer>yes</answer>
<answer>no</answer>
<response userIdRef="bob">yes</response>
<response userIdRef="jane">no</response>
</question>
<question id="q102">
<text>What is your favorite color?</text>
<answer>red</answer>
<answer>blue</answer>
<answer>white</answer>
<answer>yellow</answer>
<response userIdRef="bob">white</response>
<response userIdRef="jane">blue</response>
</question>
</survey>https://stackoverflow.com/questions/891324
复制相似问题