为什么 XML Schema 不允许我定义一对多键?我该怎么做?
我遇到了 XML 模式中令人沮丧的任意限制。出于某种原因,它坚持 PK-FK 关系必须是一对一的。为什么?
例如,给定架构:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="FutureSchema"
targetNamespace="http://tempuri.org/FutureSchema.xsd"
elementFormDefault="unqualified"
xmlns="http://tempuri.org/FutureSchena.xsd"
xmlns:mstns="http://tempuri.org/FutureSchema.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="FUTUREFILE">
<xs:complexType>
<xs:sequence>
<xs:element name="Configuration">
<xs:complexType>
<xs:sequence>
<xs:element name="Experiments">
<xs:complexType>
<xs:sequence>
<xs:element name="Experiment">
<xs:complexType>
<xs:attribute name="ID" type="xs:integer"/>
<xs:attribute name="Profile" type="xs:integer"/>
</xs:complexType>
<xs:keyref name="dummy" refer="LP">
<xs:selector xpath="Experiment"/>
<xs:field xpath="@Profile"/>
</xs:keyref>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:key name="LP">
<xs:selector xpath="*/Configuration/Profiles/Profile"/>
<xs:field xpath="@ID"/>
</xs:key>
</xs:element>
<xs:element name="Profiles">
<xs:complexType>
<xs:sequence>
<xs:element name="Profile">
<xs:complexType>
<xs:attribute name="ID" type="xs:integer"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
和一个示例实例:
<?xml version="1.0" encoding="utf-8" ?>
<b:FUTUREFILE xmlns:b="http://tempuri.org/FutureSchena.xsd">
<Configuration>
<Experiments>
<Experiment ID="1" Profile="1"/>
<Experiment ID="2" Profile="1"/>
</Experiments>
<Profiles>
<Profile ID="1"/>
</Profiles>
</Configuration>
</b:FUTUREFILE>
如果我定义
,例如;即多个实验可能不会引用相同的配置文件。但我为什么要使用关键关系呢?如果我连这么根本的事情都做不了,那么关键的关系还有什么用呢?
好吧,如果不让我这样做,我该怎么办?
编辑#1:根据要求,我填充了代码示例以包含完整的架构和基本实例。
编辑#2:有趣。 SharpDevelop 的 XML 编辑器(与 Visual Studio 相对)似乎并不反对。它也不反对引用不存在的主键的外键值(IMO 应该如此),但这是一个开始。
I'm falling over on a frustrating, arbitrary restriction in XML Schema. For some reason, it insists that PK-FK relationships have to be one-to-one. Why?
For example, given the schema:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="FutureSchema"
targetNamespace="http://tempuri.org/FutureSchema.xsd"
elementFormDefault="unqualified"
xmlns="http://tempuri.org/FutureSchena.xsd"
xmlns:mstns="http://tempuri.org/FutureSchema.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="FUTUREFILE">
<xs:complexType>
<xs:sequence>
<xs:element name="Configuration">
<xs:complexType>
<xs:sequence>
<xs:element name="Experiments">
<xs:complexType>
<xs:sequence>
<xs:element name="Experiment">
<xs:complexType>
<xs:attribute name="ID" type="xs:integer"/>
<xs:attribute name="Profile" type="xs:integer"/>
</xs:complexType>
<xs:keyref name="dummy" refer="LP">
<xs:selector xpath="Experiment"/>
<xs:field xpath="@Profile"/>
</xs:keyref>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:key name="LP">
<xs:selector xpath="*/Configuration/Profiles/Profile"/>
<xs:field xpath="@ID"/>
</xs:key>
</xs:element>
<xs:element name="Profiles">
<xs:complexType>
<xs:sequence>
<xs:element name="Profile">
<xs:complexType>
<xs:attribute name="ID" type="xs:integer"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
And an example instance:
<?xml version="1.0" encoding="utf-8" ?>
<b:FUTUREFILE xmlns:b="http://tempuri.org/FutureSchena.xsd">
<Configuration>
<Experiments>
<Experiment ID="1" Profile="1"/>
<Experiment ID="2" Profile="1"/>
</Experiments>
<Profiles>
<Profile ID="1"/>
</Profiles>
</Configuration>
</b:FUTUREFILE>
Document validation throws an error if I define <Experiment ID="1" FK="1"/><Experiment ID="2" FK="1"/>
, for example; i.e. more than one Experiment may not reference the same Profile. But why else would I want to use a key relationship? What use is a key relationship at all if I can't do something so fundamental?
OK, if and won't let me do this, how should I?
edit #1: As requested, I've padded out my code sample to include the full schema and a basic instance.
edit #2: Interesting. SharpDevelop's XML editor (as opposed to Visual Studio's) doesn't seem to object. It doesn't object to the foreign key value referring to a nonexistent primary key either (which IMO it should) but it's a start.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
有什么不清楚吗?...我的英语,全部:-)
一些评论,我不确定它是解决方案:
在示例中,最好使用
xmlns:b="http://tempuri. org/FutureSchema.xsd">
,而不是xmlns:b="http://tempuri.org/FutureSchena.xsd">
(n -> m)。另外,最好将 b: 放在所有元素名称前面。
根据您的架构,实验中不能有两个实验,只能有一个。
在 xsd 上,放置
,这最适合我;这是因为 xpath 表达式不理解默认命名空间,请参阅 使用 key 的正确方法xsd。What wasn't clear ?... My english, it's all :-)
Some remarqs, I'm not sure it's solution :
In exemple instance, it's best to use
xmlns:b="http://tempuri.org/FutureSchema.xsd">
, and notxmlns:b="http://tempuri.org/FutureSchena.xsd">
(n -> m).Also it's best to put b: in front of all elements names.
According to your schema, you can't have two Experiment in Experiments, only one.
On xsd, put
<xs:keyref name="dummy" refer="mstns:LP">
, that works best for me ; it's because xpath expression doesnt't understand default namespace, see Correct way to use key in xsd.