想这么设置:当xml文件包含多个相同元素时,如果这些元素的字段在该属性值上有重复,则不能通过Schema验证。请问能否在schema文件里定义,对于指定的某个属性值设置成类似于数据库的主键?
---------------------------------------------------------------
moonpiazza(月下小生) ( ) 信誉:110 2003-4-29 19:50:03 得分:0
XML数据类型中有一种特殊的属性值类型:ID,其不可重复设置相同的属性值
:_)
beachday(引擎) ( ) 信誉:100 2003-4-30 10:43:28 得分:0
呵呵,谢谢moonpiazza(月下小生),我试出来了,谢谢你。还有一个问题想请教一下,我用的是XmlSpy编辑工具,每个元素的下面框里有一个Identity Constraints, 里面有name,refer,selector和field(s)。请问这些字段有什么用处呢?:)
暂未使用XmlSpy,大致看了一下,以对XSD的了解,做了测试.
以下个人见解,仅供参考,不实之处,望见告,共学习之.
XML Schema
使用unique,key,keyref来进行数据的唯一性约束,描述数据间复杂的关系映射,是XML Schema相对于DTD的优势。
如果曾经尝试用 DTD 来描述具有复杂关系映射的关系数据库,那么好象必须使用 ID-IDREF指向机制。例如,在一个结构中,两个实体通过一张关系表表示相互联系的多对多关系(例如,BBS论坛应用中用户和帖子),简单的 XML 父子关系是不够的。然而,ID 和 IDREF 有其自身弱点:在整个文档中,ID 必须是唯一的,并且 IDREF 声明没有指定 IDREF 属性的实例必须引用的元素类型。XML Schema,提供了一种与关系数据库中声明的外键关系几乎相同的方式来指定这些指向关系。例如,BBS论坛中用户表与帖子表有一个外键关系,该外键关系不能用XML中简单的父子关系来表达。
key,keyref示例:bbs.xsd
在 PubUser 元素的复合类型中的键定义声明了 nUserID 属性必须出现在所有 nUserID 元素中,并且在 PubUser 元素上的所有 nUserID 属性中它必须是唯一的(注意,这与 ID 不同,无论与该元素相关的是什么元素,该 ID 是唯一的)。然后,在 BbsThread 元素的复合类型中的 keyref 定义声明了 nUserID 字段必须与文档中的 PubUser 元素的 nUserID 字段之一到处相匹配。这种键机制的另一好的特性是,该键可能是强类型 -与 ID 和 IDREF 相反,它们必须是 XML 名称标记 -所以您可以在表中不加修改地使用自动递增的主键。定义组合键以便创建主键(用 key 元素)和外键(用 keyref 元素)也是可能的,这些键直接映射到现有关系数据库中出现的主键(或外键)。
bbs.xsd
1<xsd:schema attributeformdefault="unqualified" elementformdefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
2<xsd:element name="moonpiazza">
3<xsd:complextype>
4<xsd:sequence>
5<xsd:element maxoccurs="unbounded" name="PubUser">
6<xsd:complextype>
7<xsd:attribute name="nUserID" type="xsd:int"></xsd:attribute>
8<xsd:attribute name="cUserName" type="xsd:string"></xsd:attribute>
9</xsd:complextype>
10<xsd:key name="PubUserPK"> \--> 定义键 PubUserPK
11<xsd:selector xpath=".//PubUser"></xsd:selector> \--> 指明元素路径
12<xsd:field xpath="@nUserID"></xsd:field> \--> 指明元素名称
13</xsd:key>
14</xsd:element>
15<xsd:element maxoccurs="unbounded" name="BbsThread">
16<xsd:complextype>
17<xsd:attribute name="nBbsThreadID" type="xsd:int"></xsd:attribute>
18<xsd:attribute name="nUserID" type="xsd:int"></xsd:attribute>
19<xsd:attribute name="cThreadTitle" type="xsd:string"></xsd:attribute>
20</xsd:complextype>
21<xsd:key name="BbsThreadPK"> \--> 定义键
22<xsd:selector xpath=".//BbsThread"></xsd:selector>
23<xsd:field xpath="@nBbsThreadID"></xsd:field>
24</xsd:key>
25<xsd:keyref name="BbsThreadFK" refer="PubUserPK"> \-->定义键BbsThreadFK,refer指明映射到键PubUserPK
26<xsd:selector xpath=".//BbsThread"></xsd:selector> \--> 指明元素路径
27<xsd:field xpath="@nUserID"></xsd:field> \--> 指明元素名称
28</xsd:keyref>
29</xsd:element>
30</xsd:sequence>
31</xsd:complextype>
32</xsd:element>
33</xsd:schema>
beachday(引擎) ( ) 信誉:100 2003-05-08 15:52:00 得分:0
我看了w3c那份schema的标准说明(@ @),的确是这样,在整个文档中,ID 必须是唯一的,对于多主键的情况,ID就无法限制这个组合键中某字段的可重复性了。这时候,可以通过设置Identity Constraints下,key方法中的field(s)来达到需要的数据完整性和约束性。而selector里面填的是xpath表达式,用于标明希望约束的元素的路径,如你例子中的
1<xsd:selector xpath=".//PubUser"></xsd:selector>
。