XML 视图中的 ID 属性


XML 视图定义了一种以 XML 为中心的,有关在关系数据库中存储的数据子集的视图。通过向 XML 架构添加批注形成映射架构,可以定义一个 XML 视图。

在“在 XML 视图中筛选值”(2002 年 11 月发表,InstantDoc ID 26715)与“定义 XML 视图”(2002 年 12 月发表,InstantDoc ID 27106)两篇文章中,我展示了如何使用多个批注,将数据库表中行与列的数据映射到虚拟 XML 文档中,该虚拟 XML 文档是映射架构所定义的。在这篇专栏文章中,我将展示如何使用XML 对 ID 与 IDREF 属性以及 IDREFS 属性的内置支持。ID 和 IDREF 属性的功能类似于数据库中的键与外键;IDREFS 属性则允许您指定一对多 (1:M) 的关系。您可以使用 ID 和 IDREF 属性来避免在 XML 查询结果中产生冗余数据。当数据库包含一对多的关系时,就可能发生冗余情况。例如,正如在 Northwind 示例数据库中所作的操作一样,多个定单详细信息记录可能会引用同一种产品。通过使用每种产品元素各自的 ID 属性与定单详细信息的 IDREF 属性来引用这种产品,您可以避免复制每种定单详细信息中的产品数据。尽管多个定单的详细信息都可能引用该产品元素,但是由于您只涉及一种产品元素,所以,使用这些属性减少了 XML 查询结果的大小。我还解释了如何在 SQL Server 2000 与 SQL Server 2000 Web releases (SQLXML) 中使用映射架构的前缀批注,来生成包含 ID、IDREF 与 IDREFS 属性的 XML。

当一个架构使用 ID、IDREF 或 IDREFS 类型声明属性时,使用前缀批注。 (请注意在这篇专栏文章中,ID、IDREF 与 IDREFS 属性总是指类型,而非名称。 ????架构声明的属性可以使用任何有效的属性名。) 这些特殊的属性类型在 XML 文档的不同元素间构建非层次关系。 (在非层次关系中,XML 文档中的两个元素相互关联,但是其中任何一个元素都不是另外一个元素的祖先或后代。) 当构建非层次关系时,您使用 ID 属性来指定一个在文档范围内使用的唯一键。 将这个唯一键当作 SQL Server 数据库中的主键。 —正如您会想到的一样,一个 IDREF 属性引用一个包含 ID 属性的元素,这个 ID 属性的值与 IDREF 属性的值相同 ?? 类似于 SQL Server 数据库中的外键。 使用 ID 与 IDREF,您可以在 XML 文档元素之间建立一对一 (1:1) 的关系。 IDREFS 与 IDREF 类似。它们只有一点不同:IDREFS 属性包含一个或多个对元素的引用,这些元素含有与 IDREFS 属性中指定值相同的 ID 属性。 IDREFS 属性中的各个引用被空格分隔。 如上所述,您可以用 IDREFS 来指定一对多的关系。

您映射到 ID、IDREF 与 IDREFS属性中的值必须符合特定的格式设置要求。一个 IDREFS 属性的格式设置隐含约束您用作 ID 属性的值;这些值不能包含空格字符(这是因为空格会将 ID 值分开)。对 ID 属性值的约束只是更多约束的一部分。更多的约束规定您用作 ID、IDREF 的值以及 IDREFS 属性的每个值必须满足 NCName 生产(一套用于构造受约束字符串值的规则)的要求。NCName 生产是 XML 中为命名空间的规范而定义的。(有关这种生产的信息,请参阅 http://www.w3.org/tr/1999/rec-XML-names-19990114/)。NCName 生产指定了一个有效的 NCName?¨即一个有效 ID 值)必须是一个以字母或下划线 (_) 字符开始的字符串,其后是可打印的字符或数字。因为 ID 值必须以字母或下划线开始,所以需要前缀批注符合 NCName 生产约束。

在文档的所有元素中,ID 属性值也必须是唯一的。即使元素名不同,也不允许重复。把 ID 属性作为表的主键,只是这个键带有额外约束,您不能在任何数据库其他表中使用这个键值。考虑了这些约束之后,再看一下如何把 ID、IDREF 与 IDREFS 属性映射到 SQL Server 数据库中。

因为在一个 XML 文档内部 ID 属性的值必须是唯一的,这个值非常容易把它本身映射到数据库主键中。通常情况下,您能够映射一个主键或一个 IDENTITY 列的值,来标识数据库表中一个实体的单独实例。在Listing 1所示的示例数据库中,您使用一个唯一的 OrderID 来标识存储在 Orders 表中的单个定单。您可以使用这些唯一值来产生一个 Order 元素的 ID 属性。它将唯一标识从 SQL Server 获取的 XML 结果中的定单。记住 ID 属性必须满足 XML 规范中定义的 NCName 生产的要求。但是,在 Listing 1 中,OrderID 列是以数字开头的整型。另外,如果要把 Order 与 Product 元素合并到一个文档中,您必须保证为它们的 ID 使用两个不同的值。但是,在 Listing 1 中,OrderID 列与 ProductID 列中有重复的值。如果您使用这些列的值,XML 文档将是无效的,这是因为一个定单与一种产品将共享同一 ID 属性。使用前缀批注解决了这两个问题。

您在映射架构中使用 ID、IDREF 与 IDREFS 属性的前缀批注来指定一个任意字符串,该字符串将被添加到从数据库检索到的值中,并且被映射到那些属性中。通过让您确保映射到 ID 属性的数值型值满足 NCName 生产的要求,前缀的使用就解决了第一个问题。您也可以使用非数值型前缀。前缀也能解决重复值的问题。通过为架构中的每个 ID、IDREF 或 IDREFS 属性指定单独的前缀批注,您可以从不同列中消除重复值(当您正在映射到 IDENTITY 列时,这是一个常见问题)。现在,让我们看一个如何使用前缀批注的示例。

示例使用 Listing 1 中 SQL 脚本定义的数据库。这个脚本借用 Northwind 示例数据库中的数据来生成三个表。它们把定单,定单上的行项(被称为项并且存储在 Order Details 表中),以及在行项中引用的产品联系起来。您能够通过使用 Listing 1 中的 SQL 脚本创建的数据库来运行 XML 架构定义 (XSD) 映射架构示例。

Listing 2显示了图 1所示生成 XML 结果的映射架构。在 Listing 2 的标注 C 中,映射架构声明了一个名为 root 的顶级元素,它包含一系列 Order 元素和 Product 元素。标注 A 中的 Order 元素有一个唯一标识 Order 元素的 OrderID 属性。前缀批注把 ORDER- 字符串添加到 OrderID 列的值中,这样,OrderID 属性的值就满足了 NCName 生产的要求。每个 Order 元素还包含一个 ShipAddress 与 ShipCountry 元素,以及一组 LineItem 元素 ?? 每个元素用于一个定单的行项(在 Order Details 表上可找到)。每个 LineItem 元素包含一个名为 Product 的 IDREF 属性。映射架构使用关系批注把 IDREF 属性映射到 Products 表中,并且前缀批注指定 PRODUCT-的值,以使来自 ProductID 列的值是唯一的。在标注 B 中声明的 Product 元素包含一个子元素,这个子元素含有 Product 名称和名为 ProductID 的 ID 属性。前缀批注规定应该把 PRODUCT-字符串添加到被映射列的值中,以确保 Product 元素的 ID 值与 Order 元素下 LineItem 元素的 IDREF 的值相同。

为了执行示例中的代码,需要使用 IIS 虚拟目录管理创建一个虚拟目录。这个虚拟目录管理用于 Microsoft 管理控制台 (MMC) 的 SQLXML 插件。把虚拟目录命名为 Jan2003,并在系统上选择一个目录作为本地路径。(选择 Inetpub\www 目录下的目录可以避免访问安全问题。)在名为 Orders.xsd. 的文件中把 Listing 2 中的映射架构保存到目录下。输入安全参数以访问数据库,这个数据库包含来自 Listing 1 的表。然后在 Settings 选项卡上选择 Allow XPath 复选框。在 Virtual Names 选项卡上,创建一个名为 Orders 的虚拟名称,将其类型选为 schema,然后将路径设置为 (.),它将使用为虚拟目录指定的相同目录。下一步,保存虚拟目录。到目前为止,您已经安装了 XML 视图。它用 ID 与 IDREF 来定义非层次关系。

现在,使用 Internet Explorer (IE) 5.0 或更高版本来执行 XML 视图上的 XPath 查询。通过使用 IDREF 属性把 LineItems 元素与它们引用的产品关联起来,该查询返回一个 XML 结果。要执行一个查询,在地址栏中键入 http://localhost/Jan2003/Orders/Orders.xsd/root。Jan2003/Orders/Orders.xsd 选择 Listing 2 的映射架构所定义的 XML 视图,/root 是检索所有客户的 XPath 查询。查询产生如图 1 所显示的结果。

学会如何从 SQL Server 内部数据生成 ID、IDREF 与 IDREFS 属性之后,就可以在下面两种情况下使用这种技术:架构定义 ID、IDREF 或 IDREFS 属性,或者您希望通过消除低级层次结构中的重复数据来减少 XML 结果的大小

 

 

本文作者:
« 
» 
快速导航

Copyright © 2016 phpStudy | 豫ICP备2021030365号-3