开放内容是 XML 文档中一组不会在文档架构中专门进行定义的元素和属性。简单地说,您可以将开放内容视为 XML 文档中您的程序不会专门去访问的的元素和属性。在四月份的专栏文章(“‘Open’ XML Content”,InstantDoc ID 37840)中,我解释了如何通过使用 OpenXML、XML Bulk Load 和 updategram 在 SQL Server 2000 中存储开放内容,使支持 XML 的应用程序实现可扩展性。该方案要求您在 SQL Server 数据库中存储一个 XML 格式的价格表,其中包括开放内容。在本文中,我们将继续讨论该方案,了解如何从 SQL Server 数据库提取开放内容,通过将该开放内容与您的客户下达定单的每个行项目包括在一起,将它发送给履行定单的提供商。如果您没有上个月的示例数据库,可以在 http://www.sqlmag.com 输入 InstantDoc ID 37840,下载代码来创建此数据库。chin a i t p oe er . co mS0SV8Pe
您可以选择几种不同的方法从数据库提取开放内容。使用一种简单的方法,您就可以通过普通的 SQL 查询检索数据(与返回 XML 的 SQL 查询正好相反),然后通过使用所选的编程 API 将结果处理为 XML(如图 1 所示)。您也可以使用直接返回 XML 的查询,在这种情况下,有两个选择。一个选择是,您可以使用 FOR XML EXPLICIT 来编写在查询中包括开放内容并返回 XML 的 SQL 查询。另一个选择是,您可以使用在虚拟 XML 文档中包括开放内容的 XML 视图,通过使用 XML 路径语言 (XPath) 可以查询虚拟 XML 文档。在这两个选择方案中,SQL Server 会将数据库中存储的开放内容与您在查询的其他部分指定的 XML 结果进行合并。选择的方法取决于您的编程环境。您可以用许多方式实现这一简单的方法 - 从简单文本操作到通过使用对象模型来处理 XML。另外两种方法使用 SQL Server 的 XML 支持,下面我们来更详细地了解上述方法。chin a i t p oe er . co mS0SV8Pe
FOR XML EXPLICIT 查询chin a i t p oe er . co mS0SV8Pe
利用 FOR XML 子句,您可以直接从 SQL Server 2000 获得 XML 结果。FOR XML 支持三种操作模式:Raw、Auto 和 Explicit。每个选项都会改变您的查询返回的 XML 的格式。Explicit 模式是唯一支持开放内容的模式。Explicit 模式使您可以完全控制 XML 查询结果的形状(有时也称为 XML 语法或架构)。使用 Explicit 模式查询,您可以指定 XML 文档的层次结构以及文档内的元素和属性的名称。chin a i t p oe er . co mS0SV8Pe
您可以通过在 SQL 查询中指定特殊结构化列别名来指定这些名称。结构化列的别名包含四个逻辑字段,每个字段之间用感叹号分隔。第一个字段指定父元素的名称,第二个字段指定元素在得到的 XML 文档中的嵌套方式,第三个字段(如果不是空的)指定包含列数据的元素或属性的名称。第四个字段指定格式设置指令。格式设置指令会使得列数据以一种特殊的方式进行格式设置。例如,cdata 指令包括 CDATA 节内的列数据。(CDATA 节是一种避免在列数据中用 和代替和字符的特殊方式。有关详细信息,请参阅 XML 语言规范,网址是 http://www.w3.org/TR/REC-xml#sec-cdata-sect。)另一个格式设置指令 xmltext 指定列的内容应该与查询返回的 XML 结果合并。下面我们将讨论 xmltext 指令如何工作的示例。chin a i t p oe er . co mS0SV8Pe
在该示例的情况中,一旦您批准处理客户的定单,则需要将定单发送给履行定单的提供商,然后,提供商将货物发运给您的客户。在实际应用中,定单会包含许多要在您和履行定单提供商之间进行交换的数据。为简单起见,我们只讨论您如何在定单中包括行项目的开放内容。当您处理来自供应商的价格表时,您会存储各个产品的开放内容。现在,您需要将开放内容与发送给履行定单的提供商的定单包括在一起。chin a i t p oe er . co mS0SV8Pe
为简单起见,我不提供将示例 Orders 表与 Products 表联接起来的代码;这是一个简单的关系查询。我们将重点放在如何从 Products 表提取行项目上。清单 1 说明了提取 ProductID 为 22 的产品的 FOR XML EXPLICIT 查询的使用。注意,SELECT 清单中的最后一列使用指定 xmltext 指令的列别名。此列检索开放内容。现在,我们来看看图 1 的 Overflow 列中的值。Product 元素包括重量属性和 QuantityPerUnit 子元素。由于查询中包括了 xmltext 指令,SQL Server 向图 2 展示的查询结果添加了重量属性和 QuantityPerUnit 元素。利用 xmltext 指令,可以轻松地在查询结果中包括开放内容。chin a i t p oe er . co mS0SV8Pe
要执行清单 1 中的代码,请打开查询分析器,选择 April2003 示例数据库。然后,将代码复制到查询分析器,按 F5 执行代码。现在,您应该会看到图 2 展示的结果(在执行查询检索文本结果之前按 Ctrl-T)。注意,SQL Server 在查询构造的 LineItem 元素中包括了重量属性和 QuantityPerUnit 元素。要看到 xmltext 指令对输出的效果,可从 SELECT 清单删除 Overflow 列,然后重新运行查询,或删除该指令即可。还可以尝试 xml 指令,该指令直接在 LineItem 元素内包括了 Overflow 列的完整文本。chin a i t p oe er . co mS0SV8Pe
XML 视图chin a i t p oe er . co mS0SV8Pe
既然您已经了解了 FOR XML EXPLICIT 查询如何在其结果中包括开放内容,接下来我们讨论查询开放内容的另一种方式:使用 XML 视图。XML 视图将 SQL Server 数据库中的数据显示为虚拟的 XML 文档。这种虚拟文档的结构由包括批注的 XML 架构定义 (XSD) 架构来定义,以便将您在架构中定义的元素和属性映射到数据库中表的行和列。该架构和批注共同称为映射架构。您可以使用 XPath 查询来查询映射架构定义的 XML 视图。有关 XML 视图的详细信息,请参阅我于 2002 年 12 月到 2003 年 12 月在 XML Explorer 专栏上发表的文章,或参阅随 SQLXML 3.0 Web 发布版本提供的出色文档 (http://msdn.microsoft.com/library/default.asp?url=/downloads/list/sqlserver.asp)。现在我们重点讲述在通过 XML 视图显示的虚拟 XML 文档中包括开放内容。chin a i t p oe er . co mS0SV8Pe
XML 视图支持特殊批注 - 溢出字段,它的作用很像我们在 FOR XML EXPLICIT 查询中使用的 xmltext 指令。要在 XML 视图中的元素内包括开放内容,应在映射架构中包括有关元素定义的溢出字段批注。将溢出字段批注的值设置为数据库中包含开放内容的列的名称。当您对包括带有溢出字段批注的元素的 XML 视图执行 XPath 查询时,SQL Server 会将开放内容与该元素的其他属性和子元素合并起来。现在我们来看一个简单的示例,该示例使用的数据与 FOR XML EXPLICIT 节使用的数据相同。chin a i t p oe er . co mS0SV8Pe
清单 2 中的映射架构为清单 1 的 FOR XML EXPLICIT 查询返回的同一文档定义了 XML 视图。该代码使用 relation 批注将 LineItem 元素映射到 Products 表(通过使用 SQL 前缀对所有批注进行命名空间限定)。Products 表中的每一行在 XML 视图中生成一个 LineItem 元素。该代码还包括了有关 LineItem 元素的定义的溢出字段批注,以指定 SQL Server 在构造 LineItem 元素时应该包括 Overflow 列中的开放内容。正如您看到的那样,包括开放内容相当简单。chin a i t p oe er . co mS0SV8Pe
现在,我们来运行示例代码。首先将清单 2 中的映射架构保存到计算机上名为 products_map.xml 的文件。还要将 清单 3 中的 VBScript 代码保存到您保存映射架构的同一目录中名为 opencontent.vbs 的文件。您可能需要通过编辑脚本来调整环境的连接设置。现在,在该目录中打开命令提示,执行 opencontent.vbs。在弹出的窗口中,脚本代码将展示它从数据库检索的 XML。可能需要安装 Windows Script 才能执行 opencontent.vbs。您可以从 http://msdn.microsoft.com/scripting 下载 Windows Script。chin a i t p oe er . co mS0SV8Pe
限制chin a i t p oe er . co mS0SV8Pe
在 XML 查询结果中包括开放内容时,您需要考虑两个限制因素:元素顺序和命名冲突。当 SQL Server 将开放内容中的属性和元素与查询创建的元素和属性进行合并时,它不会保留元素或属性的关系排序。无论列在查询中的顺序如何,开放内容中的所有元素始终排在查询生成的元素之前。chin a i t p oe er . co mS0SV8Pe
SQL Server 将开放内容中的属性追加到查询生成的属性列表中。但根据定义,属性是无序的,其关系顺序没有什么意义。您可以在图 2 中看到这些限制的结果。注意,来自开放内容的 QuantityPerUnit 元素排在 ProductName 和 Price 元素之前,这两个元素是查询直接生成的,重量属性出现在 ID 属性之后。如果元素在 XML 查询结果中的顺序具有某种意义 - 如果您所遵循的架构规定了特定顺序就可能会有一些意义 - 您应该选择另一种存储格式来存储保留顺序的数据。例如,您可以直接在文本列中存储 XML 表示形式。chin a i t p oe er . co mS0SV8Pe
第二个限制涉及到开放内容中的元素名称和属性名称。您可能会遇到开放内容与查询直接生成的属性和元素之间的命名冲突问题。发生冲突时,SQL Server 使用一组简单的规则来生成查询结果。当属性名称冲突时,SQL Server 会放弃开放内容中的冲突属性。结果中只出现查询直接生成的属性。chin a i t p oe er . co mS0SV8Pe
SQL Server 对待元素的方式有所不同。它不检测冲突的元素名称;而只是将来自开放内容的元素添加到查询生成的元素中。因为我前面提到的排序行为,来自开放内容的重复元素将排在查询生成的元素之前。这样可能导致由重复元素引起的分析-验证错误,或导致由对元素顺序有依赖关系的代码引起的意外运行时错误。避免此类错误的最佳方法是,确保您不会在数据库的列中以及开放内容中存储重复的数据,并且查询不会显式包括重复数据。这些限制同时适用于 FOR XML EXPLICIT 查询和 XML 视图,因为 XML 视图通过执行 FOR XML EXPLICIT 查询从 SQL Server 检索数据。chin a i t p oe er . co mS0SV8Pe
通过开放内容实现可扩展性chin a i t p oe er . co mS0SV8Pe
通过使用我在本期专栏文章和以前的专栏文章中描述的方法,您可以在数据库中存储开放内容,并在 XML 查询结果中包括开放内容。利用这些方法和技术,您现在可以创建灵活的可扩展应用程序,这些应用程序非常适合在其将来接收和发送的数据中保留开放内容。chin a i t p oe er . co mS0SV8Pe
Word教程网 | Excel教程网 | Dreamweaver教程网 | Fireworks教程网 | PPT教程网 | FLASH教程网 | PS教程网 |
HTML教程网 | DIV CSS教程网 | FLASH AS教程网 | ACCESS教程网 | SQL SERVER教程网 | C语言教程网 | JAVASCRIPT教程网 |
ASP教程网 | ASP.NET教程网 | CorelDraw教程网 |