XML 和 Internet 支持概述

Microsoft® SQL Server™ 2000 引入了支持 XML 功能的新特性。这些功能组合在一起使 SQL Server 2000 成为可支持 XML 的数据库服务器。这些新特性包括：

  • 能够使用 HTTP 访问 SQL Server。

  • 支持 XDR（XML数据简化）架构并且能够指定对这些架构的 XPath 查询。

  • 能够检索并写入 XML 数据：
    • 使用 SELECT 语句和 FOR XML 子句检索 XML 数据。

    • 使用 OPENXML 行集提供程序写入 XML 数据。

    • 使用 XPath 查询语言检索 XML 数据。
  • 增强了 Microsoft SQL Server 2000 OLE DB 提供程序 (SQLOLEDB)，使得可以将 XML 文档设置为命令文本并以流的形式返回结果集。

有关 SQL Server 对 XML 支持的最新更新，请参见 Microsoft Web 站点的 MSDN® 上的 XML Developer Center（XML 开发人员中心）。

说明 Msxml2.dll 是随 SQL Server 2000 一起安装的，但不安装其它工具。例如不安装 Xmlinst.exe，该工具用于配置 Microsoft Internet Explorer 以使用 MSXML2。完整的 MSXML2 包必须安装，以获得该功能。MSXML2 可以从 Microsoft Web 站点的 MSDN 上的 XML Developer Center 下载。

XML 入门

若要使用 Microsoft SQL Server 2000 提供的 XML 功能，必须使用过 XML、URL 语法和 HTTP 方法。还应熟悉下列术语：

XML 文档

是包含 XML 元素和特性的文档。

文档类型定义 (DTD)

定义可用于 XML 文档的元素和特性。

样式表

描述格式化或显示数据的方式。可扩展样式表语言 (XSL) 是 XML 文档中常用的语言。

窗体

是用于收集和提交数据以进行处理的结构化文档。

模板

在 SQL Server 2000 中引入的概念，模板是包含一个或多个 SQL 语句的有效 XML 文档。模板文件用于指定查询（SQL 和 Xpath 查询）。不是在 URL 中指定查询，而是在 URL 中指定包含查询的模板文件。

虚拟根

由 Microsoft Internet 信息服务 (IIS) 引入的概念，通常将虚拟根作为 IIS 的一部分进行管理。

请参见

使用用于 SQL Server 的 IIS 虚拟目录管理实用工具

使用 HTTP 访问 SQL Server

使用带批注的 XDR 架构创建 XML 视图

使用 XPath 查询

检索和编写 XML 数据


用于 SQL Server 的 IIS 虚拟目录管理

提供用于 SQL Server 的 IIS 虚拟目录管理实用工具是为了创建专用于 Microsoft® SQL Server™ 2000 的虚拟根。可以用两种方式与用于 SQL Server 的 IIS 虚拟目录管理应用程序交互：

  • 使用用于 SQL Server 的 IIS 虚拟目录管理实用工具以图形方式交互。

  • 使用用于 SQL Server 的 IIS 虚拟目录管理对象模型以编程方式交互。

请参见

使用 HTTP 访问 SQL Server


IIS 虚拟目录管理系统要求

可以在运行任何 Microsoft® Windows NT® 4.0 或 Microsoft Windows® 2000 版本的计算机上运行用于 SQL Server 的 IIS 虚拟目录管理实用工具。运行 Windows NT 4.0 的计算机要求：

  • Microsoft Internet Information Server 4.0 或更高版本（或 Windows NT Workstation 4.0 上的 Peer Web Services 4.0 或更高版本）。

  • Microsoft Management Console 1.2（由 Windows NT Option Pack 和 SQL Server 2000 安装程序安装）

对于运行 Microsoft Windows 2000 Professional 的计算机，必须安装管理工具包 (Adminpak.msi)。该文件位于 Windows 2000 Server 版的 %windir%\System32 文件夹内。


使用用于 SQL Server 的 IIS 虚拟目录管理实用工具

在使用 HTTP 访问 Microsoft® SQL Server™ 2000 数据库之前，必须安装适当的虚拟目录。在运行 Microsoft Internet 信息服务 (IIS) 的计算机上，使用用于 SQL Server 的 IIS 虚拟目录管理实用工具（在"SQL Server 工具"程序组中单击"在 IIS 中配置 SQL XML 支持"）定义并注册新的虚拟目录，即所谓的虚拟根。该实用工具指示 IIS 在新的虚拟目录和 Microsoft SQL Server 实例之间创建关联。有关该实用工具用户界面的信息，请参见 IIS 虚拟目录管理实用工具。

必须将 IIS 服务器和虚拟目录的名称指定为 URL 的一部分。虚拟目录（包括登录、密码和访问权限）中的信息用于建立与特定数据库的连接并执行查询。

可以指定 URL：

  • 直接访问数据库对象，例如表。

    在这种情况下，URL 将包括 dbobject 类型的虚拟名称。

  • 执行模板文件。

    模板是由一个或多个 SQL 语句组成的有效的 XML 文档。在 URL 中指定模板文件时，将执行存储在模板文件中的 SQL 命令。可以直接在 URL 中指定 SQL 查询，但考虑到安全性，不建议这样做。

  • 执行 XPath 查询。

    对指定作为 URL 一部分的带批注的映射架构文件执行 XPath 查询。

虚拟名

若要使模板文件、映射架构文件或数据库对象（如表或视图）成为 URL 的一部分，必须创建 template、schema 和 dbobject 类型的虚拟名称。将虚拟名称指定为 URL 的一部分，以便执行模板文件、对映射架构文件执行 XPath 查询或直接访问数据库。

在 URL 中指定的虚拟名称类型（template、schema、dbobject）还用于决定在 URL 中指定的文件类型（模板文件或映射架构文件）。例如，下面的 URL 使用模板访问 SQL Server 数据库：

http://IISServer/nwind/TemplateVirtualName/Template.xml

TemplateVirtualName 是 template 类型的虚拟名称，用于标识指定的文件 (Template.xml) 是模板文件。

请参见

使用 HTTP 访问 SQL Server


创建 nwind 虚拟目录

下例创建 nwind 虚拟目录。在大多数用于说明 Microsoft® SQL Server™ 2000 的 URL 访问的示例中，都使用 nwind 虚拟目录。

在创建 nwind 虚拟目录之前，需要一个与将要创建的虚拟目录相关联的物理目录（例如，C:\Inetpub\Wwwroot\nwind，此处 nwind 是与将要在以下过程中创建的 nwind 虚拟目录相关联的物理目录）。

还需要在与该虚拟目录相关联的物理目录下创建两个子目录（例如，C:\Inetpub\Wwwroot\nwind\template 和 C:\Inetpub\Wwwroot\nwind\schema）。这些是与 template 和 schema 类型的虚拟名称相关联的目录，这两种类型的目录是作为创建 nwind 虚拟目录的一部分而创建的。

创建 nwind 虚拟目录

  1. 在 Microsoft SQL Server 程序组中，单击"在 IIS 中配置 SQL XML 支持"。

  2. 展开服务器，然后单击想要的 Web 站点。

  3. 在"操作"菜单上指向"新建"子菜单，然后单击"虚拟目录"命令。新虚拟目录的属性页将显示在屏幕上。

  4. 在"新的虚拟目录属性"对话框的"常规"选项卡上，输入虚拟目录的名称。对于本例，键入 nwind 和物理目录路径（例如 C:\Inetpub\Wwwroot\nwind，假设在 C:\Inetpub\Wwwroot 目录中已创建了 nwind 子目录）。或者可以使用"浏览"按钮选择目录。

  5. 在"安全性"选项卡上，选择"SQL Server"并输入有效的 SQL Server 登录信息。当进入下一个选项卡时，它将请您确认刚才输入的密码。

  6. 在"数据源"选项卡上，在"SQL Server"框中输入服务器的名称，例如 (local)；如果在指定的计算机上安装了多个实例，则输入 SQL Server 2000 实例的名称（可选）。在"数据库"框中，输入 Northwind 作为默认数据库的名称。

  7. 在"设置"选项卡上，选择"允许 URL 查询"、"允许模板查询"、"允许 XPath"和"允许 POST"选项。

  8. 在"虚拟名称"选项卡上，单击"新建"按钮以创建模板类型的虚拟名称。

    在"虚拟名称配置"对话框中：

    • 在"虚拟名称"框内输入 template（可以是用户指定的任意名称）。在"类型"列表中，选择"模板"。输入路径（例如，C:\Inetpub\Wwwroot\nwind\template，假设与虚拟目录相关联的物理目录下有一个子目录 template，但并不检查该目录是否存在）。单击"保存"按钮保存虚拟名称。
  9. 在"虚拟名称"选项卡上，单击"新建"按钮以创建架构类型的虚拟名称。
    • 在"虚拟名称"框内输入 schema（可以是用户指定的任意名称）。在"类型"列表中，选择"架构"。输入路径（例如，C:\Inetpub\Wwwroot\nwind\schema，假设与虚拟目录相关联的物理目录下有一个子目录 schema）。单击"保存"按钮保存虚拟名称。
  10. 在"虚拟名称"选项卡上，单击"新建"按钮以创建模板和架构类型的虚拟名称。
    • 在"虚拟名称"框内输入 dbobject（可以是用户指定的任意名称）。在"类型"列表中，选择 dbobject。单击"保存"按钮保存虚拟名称。
  11. 单击"确定"按钮保存设置。

这就创建了虚拟目录 nwind。默认情况下，使用该虚拟目录对 Northwind 数据库执行指定的查询。

若要测试虚拟目录，请在浏览器中键入：http://<IISServer>/nwind?sql=SELECT * FROM Employees FOR XML AUTO&root=root 并按 ENTER 键。

请参见

使用用于 SQL Server 的 IIS 虚拟目录管理实用工具


"对 SQL Server 的 IIS 虚拟目录管理"对象模型

"对 SQL Server 的 IIS 虚拟目录管理"对象模型由下列对象组成：

  • SQLVDirControl 对象

  • SQLVDirs 集合对象

  • SQLVDir 对象

  • VirtualNames 集合对象

  • VirtualName 对象

在对象模型中，由对象提供应用程序的内容和功能。对象是由相关的内容和功能组成的单元。相反，集合对象是包含相关对象集的对象。可以使用集合对象到达个别对象，所采用的方法通常是 Item。例如，可以使用 SQLVDirs 集合对象的 Item 方法访问虚拟目录之一。

在此对象模型中，SQLVDirControl 是顶层对象且是唯一可以直接创建的对象。所有其它对象都必须通过 SQLVDirControl 对象或其派生对象获得。

对象层次结构（对象模型）是应用程序中的对象彼此之间的排列方式。下例显示对象模型中用于创建虚拟根的对象层次结构。

请参见

使用 HTTP 访问 SQL Server


SQLVDirControl 对象

SQLVDirControl 是对象层次结构中可通过 Automation 直接访问的唯一对象。所有其它对象都通过该对象或其派生对象访问。

SQLVDirControl 支持下列方法：

连接

连接到特定的 Microsoft® Internet 信息服务 (IIS) 服务器。该方法使用的两个参数是：IIS Server name 和 Web Site number（元数据库树中的 Web 站点数）。如果没有提供参数，则本地服务器就是 IIS 服务器的默认值，而且把在该 IIS 服务器上选择的第一个 Web 站点（默认 Web 站点）作为默认值。

断开

从上一个连接的 IIS 服务器和 Web 站点断开连接。该方法没有参数。在连接到另一台服务器或 Web 站点之前或完成连接时，必须调用 Disconnect 关闭连接。

说明 不能发出多个 Connect 调用与许多 IIS 服务器建立连接。但是，如果试图连接到可能位于不同 Web 站点的同一台 IIS 服务器，则可以在不调用 Disconnect 的情况下多次调用 Connect。

SQLVDirs

SQLVDirs 方法检索连接到的 Web 站点的虚拟目录集合。连接到特定的 IIS 服务器和 Web 站点后，调用 SQLVDirs 以获得可访问虚拟目录对象的 SQLVDirs 集合对象。

示例

下例显示在 IIS 服务器上如何连接到特定的 IIS 服务器和 Web 站点。在 IIS 服务器上选择第一个站点。

Set ObjXML = CreateObject("SQLVDir.SQLVDirControl")
ObjXML.Connect "IISServer", "1"
Set ObjDirs = ObjXML.SQLVDirs
...

ObjXML.Disconnect


SQLVDirs 集合对象

SQLVDirs 集合对象由 SQLVDirControl.SQLVDirs 方法返回。通过使用 SQLVDirs 集合对象，可以访问特定的虚拟目录（使用 Item 方法）、创建新的虚拟目录（使用 AddVirtualDirectory 方法）或删除现有的虚拟目录（使用 RemoveVirtualDirectory 方法）。

SQLVDirs 集合对象支持下列标准方法：

Next 方法

检索下一个（或多个）虚拟目录。为 Next 指定的整数决定要检索的虚拟目录数。

Skip 方法

跳过一个（或多个）虚拟目录。为 Skip 指定的数字决定要跳过的虚拟目录数。

Reset 方法

重置第一个虚拟目录的集合索引。

Clone 方法

返回 SQLVDirs 集合对象的复本。

Count 方法

返回虚拟目录的个数。

Item 方法

检索一个虚拟目录。可以指定一个整数（从第一个虚拟目录的整数为 0 开始）或指定虚拟目录名。

SQLVDirs 集合对象还支持下列方法：

AddVirtualDirectory 方法

传递要创建的虚拟目录名。该方法使用元数据库中的所有默认值创建新的虚拟目录。但是，并未对某些属性进行设置，如默认数据库。

AddVirtualDirectory 方法或 Item 方法返回表示虚拟目录的 SQLVDir 对象。

RemoveVirtualDirectory 方法

从 Microsoft® Internet 信息服务 (IIS) 元数据库中删除虚拟目录。

示例

下例与 IIS 服务器上的第一个 Web 站点建立连接。访问所连接的 Web 站点上的第一个虚拟目录对象（索引值 0）。

Set ObjXML = CreateObject("SQLVDir.SQLVDirControl")
ObjXML.Connect "IISServer", "1"
Set ObjVDirs = ObjXML.SQLVDirs
Set ObjVDir = ObjVDirs.Item(0)
' or ObjVDirs(0) since Item() is the default
...
ObjXML.Disconnect


SQLVDir 对象

SQLVDir 对象是通过调用 Item 方法（如果创建新的虚拟目录，则调用 AddVirtualDirectory 方法）获得的虚拟目录对象。

SQLVDir 对象支持下列属性。可以获得并设置除 Password 属性（可以设置该属性的值，但不能获得它）以外的所有属性的值。

Name 属性

是虚拟目录的名称。

PhysicalPath 属性

是与虚拟目录关联的目录的完整物理路径。

ServerName 属性

是运行 Microsoft® SQL Server™ 2000 的服务器名称，这是虚拟目录的数据源。

DatabaseName 属性

是在对该虚拟目录执行的查询中所使用的默认数据库。

UserName 属性

是用于连接到数据源的用户登录。

Password 属性

是用于连接到数据源的用户密码。

SecurityMode 属性

是用于虚拟目录的登录身份验证方法，如 SQL 身份验证或 Windows 集成身份验证。可以指定下列值之一。

值 | 描述
1 | SQL Server 登录
2 | Microsoft Windows® 匿名登录
4 | 基本身份验证
8 | Windows 集成验证

注意 如果正在更改连接设置（更改服务器名、数据库名、用户名、密码或安全模式），建议禁用虚拟目录访问。可通过将 AllowFlags 设置为 0 来禁用虚拟目录。

AllowFlags 属性

提供通过该虚拟目录所允许的访问类型。可以指定下列值之一（或这些值的组合）。

值 | 描述
1 | URL 查询
8 | 模板访问
64 | XPath 查询

EnablePasswordSync 属性

指定是否允许 Microsoft® Internet 信息服务 (IIS) 处理匿名密码同步。

DLLPath 属性

提供 Sqlisapi.dll 的完整路径。

AdditionalSettings 属性

是 OLE DB 连接字符串中的用户定义设置。

SQLVDir 对象还支持下列方法：

VirtualNames 方法

是虚拟目录的虚拟名称映射集合。

示例

下例与 IIS 服务器上的第一个 Web 站点建立连接。访问所连接的 Web 站点上的第一个虚拟目录对象（索引 0）。该对象的 PhysicalPath 属性设置为 C:\inetpub。

Set ObjXML = CreateObject("SQLVDir.SQLVDirControl")
ObjXML.Connect "IISServer", "1"
Set ObjVDirs = ObjXML.SQLVDirs
Set ObjVDir = ObjVDirs.Item(0)
ObjVDir.PhysicalPath = "C:\"
ObjVDir.PhysicalPath = ObjVDir.PhysicalPath & "inetpub"
...
ObjXML.Disconnect


VirtualNames 集合对象

VirtualNames 集合对象是虚拟目录对象（SQLVDir 对象）中的虚拟名称集合。VirtualNames 集合对象与 SQLVDirs 对象（它是虚拟根对象的集合）相似。VirtualNames 集合对象支持下列标准方法：

Next 方法

检索下一个（或多个）虚拟名称。为 Next 指定的整数决定要检索的虚拟名称数。

Skip 方法

跳过一个（或多个）虚拟名称。为 Skip 指定的数字决定要跳过的虚拟名称数。

Reset 方法

重置第一个虚拟名称的集合索引。

Clone 方法

返回 VirtualNames 集合对象的复本。

Count 方法

返回虚拟名称的个数。

Item 方法

检索一个虚拟名称。可指定一个整数（从第一个虚拟目录的整数为 0 开始）或指定虚拟名的名称。

VirtualNames 集合对象还支持下列方法：

AddVirtualName 方法

传递虚拟名称的名称、虚拟名称的类型以及与要创建的虚拟名称相关联的目录路径。AddVirtualName 方法或 Item 方法返回表示虚拟名称的 VirtualName 对象接口。

RemoveVirtualName 方法

删除指定的虚拟名称。

示例

下例显示访问 VirtualNames 集合对象的步骤。

Set ObjXML = CreateObject("SQLVDir.SQLVDirControl")
ObjXML.Connect "IISServer", "1"
Set ObjVDirs = ObjXML.SQLVDirs
Set ObjVDir = ObjVDirs.Item(0)
Set ObjNames = ObjVdir.VirtualNames
...
ObjXML.Disconnect


VirtualName 对象

通过调用 Item 方法（如果创建新的虚拟名称，则调用 AddVirtualName 方法）获得 VirtualName 对象。

VirtualName 对象支持下列属性：

Name 属性

是正创建的虚拟名称的名称。

Type 属性

是虚拟名称类型。可以指定下列值之一。

值 | 描述
1 | dbobject 类型的虚拟名称。
2 | schema 类型的虚拟名称。
4 | template 类型的虚拟名称。

Path 属性

是与虚拟名称关联的目录路径（绝对或相对）。

示例

下例显示访问现有 VirtualName 对象并设置其某些特性的步骤。

Set ObjXML = CreateObject("SQLVDir.SQLVDirControl")
ObjXML.Connect "IISServer", "1"
Set ObjVDirs = ObjXML.SQLVDirs
Set ObjVDir = ObjVDirs.Item(0)
Set ObjNames = ObjVdir.VirtualNames
Set ObjVName1 = ObjNames.Item(0)
ObjVName1.Type = 2
ObjVName1.Name = "MySchema"
ObjVName1.Path = "C:\inetpub\schema"
...
ObjXML.Disconnect

下面的语句创建新的虚拟名称：

Set NewVName = ObjNames.AddVirtualName "MyNewSchema", 2, "C:\inetpub\schema"


使用对象模型创建 nwind 虚拟目录

下面的 Microsoft® Visual Basic® Scripting Edition (VBScript) 示例创建与在创建 nwind 虚拟目录中所描述的相同的 nwind 虚拟目录。

Set ObjXML = CreateObject("SQLVDir.SQLVDirControl")
ObjXML.Connect 'Connect to the local computer and Web site "1"

Set ObjVDirs = ObjXML.SQLVDirs
Set ObjVDir = ObjVDirs.AddVirtualDirectory("nwind")

'General tab in UI
ObjVDir.PhysicalPath = "C:\Inetpub\wwwroot\nwind"

'Security tab in UI
ObjVDir.UserName = "sa" 'SQL Server login
ObjVDir.Password = ""   'SQL Server Password (is "" per default)

'Data source tab in UI
'(local) is default for the SQL Server
ObjVDir.DatabaseName = "Northwind"

'Settings tab in UI
objVDir.AllowFlags = 73 'afURL_QUERIES OR afTEMPLATES OR afXPath

'Virtual Name Configuration tab in the UI
Set objVNames = objVDir.VirtualNames
objVNames.AddVirtualName "dbobject", 1, ""
objVNames.AddVirtualName "schema", 2, "C:\Inetpub\wwwroot\nwind\schema"
objVNames.AddVirtualName "template", 4 , "C:\Inetpub\wwwroot\nwind\template"

'Disconnect from the server.
objXML.Disconnect

msgbox "Done."


使用 HTTP 访问 SQL Server

可以使用 HTTP 访问 Microsoft® SQL Server™ 2000。有关 SQL ISAPI 扩展所支持的 URL 语法的更多信息，请参见 URL Access。在可以使用 HTTP 指定查询前，必须先用用于 SQL Server 的 IIS 虚拟目录管理实用工具创建一个虚拟根。有关更多信息，请参见创建 nwind 虚拟目录。

SQL Server 的 HTTP 访问能力使您得以：

  • 直接在 URL 中指定 SQL 查询，例如：
    http://IISServer/nwind?sql=SELECT+*+FROM+Customers+FOR+XML+AUTO&root=root

    指定 FOR XML 子句以 XML 文档而不是标准行集的形式返回结果。根参数可标识单一的顶层元素。

  • 直接在 URL 中指定模板。

    模板是包含一个或多个 SQL 语句的有效的 XML 文档。模板使您得以将数据放在一起以形成有效的 XML 文档，但直接在 URL 中指定查询时不一定是这样。例如：

    http://IISServer/nwind?template=<ROOT+xmlns:sql="urn:schemas-microsoft-com:xml-sql"><sql:query>SELECT+*+FROM+Customers+FOR+XML+AUTO</sql:query></ROOT>
  • 在 URL 中指定模板文件。

    在 URL 中写入长 SQL 查询会很麻烦。此外，浏览器对在 URL 中可以输入的文本量可能有限制。若要避免这些问题，可以编写模板并将其存储在文件中。模板是包含一个或多个 SQL 语句和 XPath 查询的有效的 XML 文档。可以在 URL 中直接指定模板文件，例如：

    http://IISServer/nwind/TemplateVirtualName/templatefile.xml

    在 URL 中，TemplateVirtualName 是使用用于 SQL Server 的 IIS 虚拟目录管理实用工具创建的 template 类型的虚拟名称。

    模板文件还删除来自用户的数据库查询的详细信息以增强安全性。通过将模板文件存储在注册数据库时所在的虚拟根目录（或其子目录）中，删除虚拟根上的 URL 查询处理服务并只允许 SQL Server XML ISAPI 处理文件及返回结果集，从而加强了安全性。

  • 指定在带批注的 XML 数据简化 (XDR) 架构（也称为映射架构）上执行的 XPath 查询。

    从概念上讲，对映射架构编写 XPath 查询与使用 CREATE VIEW 语句创建视图并对视图编写 SQL 查询相似，例如：

    http://IISServer/nwind/SchemaVirtualName/schemafile.xml/Customer[@CustomerID="ALFKI"]

    在这个 URL 中：

    • SchemaVirtualName 是使用用于 SQL Server 的 IIS 虚拟目录管理实用工具创建的 schema 类型的虚拟名称。

    • Customer[@CustomerID="ALFKI"] 是在该 URL 中指定的 schemafile.xml 上执行的 Xpath 查询。
  • 直接在 URL 中指定数据库对象。

    可以将数据库对象（如表和视图）指定为 URL 的一部分，并对数据库对象指定 Xpath 查询，例如：

    http://IISServer/nwind/dbobjectVirtualName/XpathQuery

    在这个 URL 中，dbobjectVirtualName 是使用用于 SQL Server 的 IIS 虚拟目录管理实用工具创建的 dbobject 类型的虚拟名称。

    说明 当在 URL 中执行需要资源（如内存）的操作（创建临时表和临时存储过程、声明游标、执行sp_xml_preparedocument 等等）时，必须执行适当的相应命令（如 DROP TABLE、DROP PROCEDURE、DEALLOCATE 游标或 EXECUTE sp_xml_removedocument）以释放资源。

XML 文档和文档片段

当用 root 参数执行模板或查询时，结果是有单个顶层元素的完整 XML 文档。例如，下列 URL 执行模板：

http://IISServer/VirtualRoot/TemplateVirutalName/MyTemplate.xml

下面是一个示例模板文件 (MyTemplate.xml)：

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
    <sql:query>
      SELECT  *
      FROM    Customers
      FOR XML AUTO
    </sql:query>
</ROOT>

模板中的 <ROOT> 标记为结果 XML 文档提供了单个的顶层元素。

可以直接在 URL 中指定查询。在此例中，root 参数指定返回文档中的顶层元素：

http://IISServer/VirtualRoot?sql=SELECT * FROM Customers FOR XML AUTO?root=root

如果在写上述查询时不使用 root 参数，将返回一个 XML 文档片段（即缺少单个顶层元素的 XML 文档）。 该片段没有标题信息。例如，下列 URL 将返回文档片段：

http://IISServer/VirtualRoot?sql=SELECT * FROM Customers FOR XML AUTO

当请求一个 XML 文档时，将返回用以标识文档编码类型的字节顺序标记。字节顺序标记是用以标识 XML 文档编码类型的标准字节顺序。XML 分析器使用该字节顺序标记确定文档编码类型（如 Unicode）。例如，字节顺序标记"oxff, 0xfe"将文档标识为 Unicode。默认情况下，分析器假设 UTF-8 为文档编码类型。

当请求 XML 片段时将不返回字节顺序标记，因为字节顺序标记属于 XML 文档标题，而 XML 片段中没有标题。

请参见

使用 FOR XML 检索 XML 文档

使用用于 SQL Server 的 IIS 虚拟目录管理实用工具


三层系统构架

下例显示三层系统构架并描述处理来自客户端的 HTTP 请求的方式。

中间层是 Microsoft® Internet 信息服务 (IIS) 服务器，必须先在该服务器上使用用于 SQL Server 的 IIS 虚拟目录管理实用工具创建虚拟根。URL 中指定的 IIS 服务器名称用来标识 IIS 服务器。IIS 服务器检查 URL 中指定的虚拟根，并确定是否已注册了 URL 中指定的虚拟根的 ISAPI DLL 扩展 (Sqlisapi.dll)。IIS 服务器装载该 DLL 并将 URL 请求传递到该 DLL。Sqlisapi.dll 扩展与用于 SQL Server 的OLE DB 提供程序 (SQLOLEDB) 通讯，并与虚拟根中标识的 Microsoft SQL Server™ 实例建立连接。

全部 XML 功能都在 Sqlxmlx.dll 中执行。当 SQLOLEDB 确定命令是 XML 命令时，该提供程序便将此命令传递到 Sqlxmlx.dll，Sqlxmlx.dll 执行命令并将结果返回给 SQLOLEDB。

模板文件、XML 数据简化 (XDR) 架构文件和可扩展样式表语言 (XSL) 文件都驻留在 IIS 服务器上。XPath 查询和 XDR 架构都在 IIS 服务器上进行处理。Sqlxmlx.dll将 XPath 查询转换成 SQL 命令。

FOR XML 子句和 OPENXML 都在运行 SQL Server 的服务器上执行。


特殊字符

一些字符在 URL 或 XML 文档中使用时有特殊的含义，因此必须针对这些含义对字符做适当编码以使其生效。

URL 中的特殊字符

在 URL 上执行的查询中，特殊字符被指定为 %xx，其中 xx 是字符的十六进制值。下表列出了这些特殊字符并描述了它们的含义。有关更多信息，请参见 http://www.faqs.org/rfcs/rfc1738.html 中的 RFC1738 规范。

特殊字符 | 特殊含义 | 十六进制值
+ | 表示空格（在 URL 中不能使用空格）。 | %20
/ | 分隔目录和子目录。 | %2F
? | 分隔实际的 URL 和参数。 | %3F
% | 指定特殊字符。 | %25
# | 表示书签。 | %23
& | URL 中指定的参数间的分隔符。 | %26

例如，考察下面的查询：

SELECT *
FROM Employees
WHERE EmployeeID=?

因为 ? 字符在 URL 中有特殊含义（分隔 URL 和传递的参数），所以在 URL 中指定该查询时，该字符被编码为 %3F。

下列 URL 将执行该查询。在 URL 中传递该参数值。有关用 HTTP 执行 SQL 语句的更多信息，请参见使用 HTTP 执行 SQL 语句。

http://IISServer/nwind?sql=SELECT * FROM Employees WHERE EmployeeID=%3F FOR XML AUTO&root=root&EmployeeID=1

浏览器将 ? 右侧的所有特殊字符（如 + 字符）都进行转义（即，将 ? 右侧的 + 字符转换成 %20）。

XML 中的特殊字符

> 和 < 这类字符是XML 标记字符，在 XML 中有特殊的含义。当在 SQL 查询（或 XPath 查询）中指定这些字符时，必须对它们进行适当的编码（也称为实体编码）。下表列出了这些特殊字符并描述了它们的含义。有关更多信息，请参见 XML 1.0 规范 中的 XML 1.0 规范。

特殊字符 | 特殊含义 | 实体编码
> | 开始标记。 | &gt;
< | 结束标记。 | &lt;
" | 引号。 | &quot;
' | 撇号。 | &apos;
& | "&"符。 | &amp;

例如，考察下面的查询：

SELECT  TOP 2 *
FROM      [Order Details]
WHERE   UnitPrice > 10
FOR XML AUTO

因为 > 字符在 XML 中有特殊含义，所以当在某模板（一个 XML 文档）中指定该查询时，该字符被编码为 &gt;。以下就是含有该查询的模板：

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:query>
      SELECT top 2 *
      FROM     [Order Details]
      WHERE     UnitPrice &gt; 10
      FOR XML AUTO
  </sql:query>
</ROOT>

有关模板的更多信息，请参见使用模板执行 SQL 查询和使用模板执行 XPath 查询。

URL 编码中的实体编码

有时可能需要同时指定 URL 编码与实体编码。例如，可在 URL 中直接指定以下模板（而不是指定文件名）：

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:query>
      SELECT top 2 *
      FROM     [Order Details]
      WHERE     UnitPrice &gt; 10
      FOR XML AUTO
  </sql:query>
</ROOT>

在此例中，（为 > 标记字符指定的）实体编码 &gt; 内的 & 字符在 URL 中有特殊含义，需要对其进行进一步编码。必须将 & 字符编码为 %26，否则在 URL 中将把它视为参数分隔符。该 URL 于是被指定为：

http://IISServer/nwind?template=<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql"><sql:query>SELECT TOP 2 * FROM [Order Details] WHERE UnitPrice %26gt; 10 FOR XML AUTO</sql:query></ROOT>

请参见

使用 HTTP 访问 SQL Server

使用 FOR XML 检索 XML 文档

使用用于 SQL Server 的 IIS 虚拟目录管理实用工具


使用 HTTP 执行 SQL 语句

在 URL 中执行的查询可以直接访问 Microsoft® SQL Server™ 2000（如果在注册虚拟根时选定了"允许 URL 查询"选项）。客户端可以使用 HTTP 方法 GET 和 POST 发出请求。有关 SQL ISAPI 扩展所支持的 URL 语法的更多信息，请参见 URL Access。

示例

在下列示例中，nwind 是用于访问 Northwind 数据库的虚拟目录。有关创建 nwind 虚拟目录的更多信息，请参见创建 nwind 虚拟目录。

在查询示例中，如果查询返回文档的多个根元素，则将包括下列之一以添加根元素：

  • 在查询中包括 SELECT <ROOT>。

  • 将 root 关键字作为参数传递到带 ROOT 值（该值可为任意值）的查询。
A. 指定简单查询

下列语句从 Northwind 数据库的 Customers 表中返回所有客户数据。在该查询中，XML 模式设置为 RAW。

http://IISServer/Nwind?sql=SELECT+top+2+CustomerID,+ContactName+FROM+Customers+FOR+XML+RAW&root=ROOT

下面是结果集：

<ROOT>
   <Customers CustomerID="ALFKI" ContactName="Maria Andears" />
   <Customers CustomerID="ANATR" ContactName="Ana Trujillo" />
</ROOT>
B. 在多个表上指定查询

在下例中，SELECT 语句从 Northwind 数据库的 Customers 和 Orders 表中返回信息。XML 模式被设置为 AUTO。

http://IISServer/nwind?sql=SELECT+top+2+Customers.CustomerID,OrderID,OrderDate+FROM+Customers,+Orders+WHERE+Customers.CustomerID=Orders.CustomerID+Order+by+Customers.CustomerID,OrderID+FOR+XML+AUTO&root=ROOT

下面是部分结果：

<ROOT>
   <Customers CustomerID="ALFKI">
     <Orders OrderID="10643" OrderDate="1997-08-25T00:00:00" />
     <Orders OrderID="10692" OrderDate="1997-10-03T00:00:00" />
   </Customers>
   <Customers CustomerID="ANATR">
     <Orders OrderID="10308" OrderDate="1996-09-18T00:00:00" />
   </Customers>
</ROOT>
C. 在查询中指定特殊字符

下列查询从 Northwind 数据库的 Customers 表中返回所有以 Sa 开头的不重复联系人的职务。下例使用 LIKE 子句和特殊字符 % 搜索联系人的职务。在 LIKE 子句中，特殊字符 % 被指定为 %25。

http://IISServer/nwind?sql=SELECT+DISTINCT+ContactTitle+FROM+Customers+WHERE+ContactTitle+LIKE+'Sa%25'+ORDER+BY+ContactTitle+FOR+XML+AUTO&root=root

下面是结果集：

<ROOT>
   <Customers ContactTitle="Sales Agent" />
   <Customers ContactTitle="Sales Associate" />
   <Customers ContactTitle="Sales Manager" />
   <Customers ContactTitle="Sales Representative" />
</ROOT>

在下例中，从 Orders 和 Order Details 表中检索订单和订单详细信息。

http://IISServer/nwind?sql=SELECT+'<ROOT>'+SELECT+Orders.OrderID,+[Order+Details].OrderID,[Order+Details].ProductID,[Order+Details].UnitPrice+FROM+Orders,+[Order+Details]+WHERE+Orders.OrderID=[Order+Details].OrderID+ORDER+BY+Orders.OrderID+FOR+XML+AUTO;SELECT+'</ROOT>'

下面是部分结果：

<ROOT>
<Orders OrderID="10248">
  <Order_x0020_Details OrderID="10248" ProductID="11" UnitPrice="14.00" />
  <Order_x0020_Details OrderID="10248" ProductID="42" UnitPrice="9.80" />
</Orders>
<Orders OrderID="10249">
  <Order_x0020_Details OrderID="10249" ProductID="14" UnitPrice="18.60" />
</Orders>
</ROOT>
D. 指定不带 FOR XML 子句的查询

可以指定不带 FOR XML 子句的 SQL 查询。以流的形式返回结果。在该查询中只能指定一列，因为在多列结果上不支持流。在下例中，查询从 Northwind 数据库的 Employees 表中返回职员的名字。以名字的串联字符串的形式返回结果。

http://IISServer/nwind?sql=SELECT+FirstName+FROM+Employees
E. 指定 contenttype 关键字

contenttype 关键字指定所返回文档的内容类型。text/XML 是文档的默认内容类型，除非在 URL 中指定 xsl。如果在 URL 中指定了 xsl 而未指定 contenttype 时，contenttype 将默认为 text/html。

在下例中，查询从 Northwind 数据库的 Employees 表中返回职员的照片。没有指定 FOR XML 模式，因为所返回的数据与接收数据的应用程序兼容（即，浏览器可以处理所返回的数据）。

http://IISServer/nwind?sql=SELECT+Photo+FROM+Employees+WHERE+EmployeeID=1

在检索图像时，通常指定 contenttype。如果指定了 contenttype，ISAPI 扩展将不搜索也不删除任何 Access 标题信息。因此，若要检索任何有 Access 标题信息的图像，则不应指定 contenttype，如上例所示。在所有其它情况下应指定 contenttype，如下例所示：

http://iisserver/virtualroot?sql=SELECT+Picture+FROM+TableName+WHERE+SomeID=1&contenttype=image/jpeg

也可以将图像引入 HTML 文档。在下例中，用这些内容创建一个 .htm 文件 (File1.htm)：

<img src="http://IISServer/nwind?sql=select photo from Employees where EmployeeID=1">

在浏览器中打开该文件时，将显示职员的照片。

F. 指定 xsl 关键字

在下例中，查询从 Northwind 数据库的Employee 表中返回所有职员的名字和姓氏。employee.xsl 处理结果集。

如果在 URL 中指定了 xsl 而未指定 contenttype，并且没有在 XSL 样式表中定义的内容类型，则 contenttype 将默认为 text/html。因此，结果将以含有两列 (firstname, lastname) 的表的形式显示。

http://IISServer/nwind?sql=SELECT+FirstName,LastName+FROM+Employees+FOR+XML+AUTO&xsl=employee.xsl&root=root

下面提供 .xsl 文件。该文件必须存在于虚拟根目录或它的一个子目录中（在这种情况下，指定的文件路径相对于虚拟根目录）。在下例中，.xsl 文件存储在虚拟根目录中。

<?xml version='1.0' encoding='UTF-8'?>
 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:template match = '*'>
        <xsl:apply-templates />
    </xsl:template>
    <xsl:template match = 'Employees'>
       <TR>
         <TD><xsl:value-of select = '@FirstName' /></TD>
         <TD><B><xsl:value-of select = '@LastName' /></B></TD>
       </TR>
    </xsl:template>
    <xsl:template match = '/'>
      <HTML>
        <HEAD>
           <STYLE>th { background-color: #CCCCCC }</STYLE>
        </HEAD>
        <BODY>
         <TABLE border='1' style='width:300;'>
           <TR><TH colspan='2'>Employees</TH></TR>
           <TR><TH >First name</TH><TH>Last name</TH></TR>
           <xsl:apply-templates select = 'root' />
         </TABLE>
        </BODY>
      </HTML>
    </xsl:template>
</xsl:stylesheet>

也可以不在 URL 中指定 contenttype，而是将其指定为 <xsl:output> 元素的 media-type 属性值。例如，在前面的 XSL 文件中的命名空间声明后可添加 <xsl:output media-type="text/html" />。

G. 将参数传递到 SQL 语句

可以将参数传递到 SQL 查询。在下例中，从 Northwind 数据库的 Employees 表中返回特定职员 ID 的职员信息。以在查询中输入的形式提供 EmployeeID 值。注意在 URL 中用作参数标记的 ? 字符是特殊字符，被编码为 %3F。有关特殊字符的更多信息，请参见特殊字符。

http://IISServer/nwind?sql=SELECT+FirstName,LastName+FROM+Employees+WHERE+EmployeeID=%3F+FOR+XML+AUTO&EmployeeID=1&root=ROOT

下面是结果集：

<ROOT>
   <Employees FirstName="Nancy" LastName="Davolio" />
</ROOT>

在此查询中，将两个参数值传递到查询：

http://IISServer/nwind?sql=SELECT+'<ROOT>';SELECT+EmployeeID,Title+FROM+Employees+WHERE+LastName=%3F+and+FirstName=%3F+FOR+XML+AUTO;SELECT+'</ROOT>'&LastName=Davolio&FirstName=Nancy

下面是结果集：

<ROOT>
   <Employees EmployeeID="1" Title="Sales Representative" />
</ROOT>

请参见

使用 HTTP 访问 SQL Server

使用 FOR XML 检索 XML 文档

使用用于 SQL Server 的 IIS 虚拟目录管理实用工具


使用 HTTP 执行存储过程

可用任何一种 Transact-SQL 执行语法在 URL 中执行存储过程：EXECUTE MySP；或 ODBC 调用语法：{call+MySP}。

可以将参数传递到存储过程。在选择参数时可以取任何没有使用的 name=value 对，并按提供的顺序将它们作为参数提供给查询。有关 SQL ISAPI 扩展所支持的 URL 语法的更多信息，请参见 URL Access。

示例

在下列示例中，nwind 是用于访问 Northwind 数据库的虚拟目录。有关创建 nwind 虚拟目录的更多信息，请参见创建 nwind 虚拟目录。

A. 执行简单存储过程

下例创建并执行从 Northwind 数据库的 Categories 表中返回分类名称的存储过程。该存储过程不带参数。

IF EXISTS (SELECT name FROM sysobjects
   WHERE name = 'CategoryInfo' AND type = 'P')
   DROP PROCEDURE CategoryInfo
GO
CREATE PROCEDURE CategoryInfo
AS
    SELECT CategoryName
    FROM     Categories
    FOR XML AUTO
GO

可以用 URL 执行该存储过程：

http://IISServer/nwind?sql=EXECUTE+CategoryInfo&root=ROOT
B. 执行带参数的存储过程

在下例中，用 URL 执行带参数的存储过程。存储过程从 Northwind 数据库的 Category 表中检索特定分类 ID 的分类名称。

IF EXISTS (SELECT name FROM sysobjects
   WHERE name = 'CategoryInfoWithInputParam' AND type = 'P')
   DROP PROCEDURE CategoryInfoWithInputParam
GO

CREATE PROCEDURE CategoryInfoWithInputParam
                    @CategoryID int
AS
    SELECT '<ROOT>'
    SELECT CategoryName
    FROM     Categories
    WHERE    Categories.CategoryID = @CategoryID
    FOR XML AUTO
    SELECT '</ROOT>'
GO

可以用 URL 执行该存储过程：

http://IISServer/nwind?sql=execute+CategoryInfoWithInputParam+1

或

http://IISServer/nwind?sql=execute+CategoryInfoWithInputParam+@CategoryID=1

第一个示例通过位置指定参数值 (1)（即，没有参数名）。第二个示例用该值指定参数名。

C. 使用 Transact-SQL EXECUTE 和 ODBC 调用语法执行存储过程

该存储过程从 Northwind 数据库的 Employees 表中返回特定职员的职员信息。该存储过程将职员的名字和姓氏作为输入，并返回职员 ID、职员的职务和出生日期。

IF EXISTS (SELECT name FROM sysobjects
   WHERE name = 'FindEmp' AND type = 'P')
   DROP PROCEDURE FindEmp
GO

CREATE PROCEDURE FindEmp @FName varchar(20), @LName varchar(20) AS
SELECT    EmployeeID, Title, BirthDate
FROM       Employees
WHERE    FirstName = @FName
AND       LastName = @LName
FOR XML AUTO
GO

可以指定 Transact-SQL EXECUTE 语句执行存储过程：

http://IISServer/nwind?sql=SELECT+'<ROOT>';EXECUTE+FindEmp+'Nancy'+,+'Davolio';SELECT+'</ROOT>'

或

http://IISServer/nwind?sql=SELECT+'<ROOT>';EXECUTE+FindEmp+@FName='Nancy'+,+@LName='Davolio';SELECT+'</ROOT>'

还可以指定 ODBC 调用语法执行存储过程：

http://IISServer/nwind?sql=SELECT+'<ROOT>';{CALL+FindEmp}+'Nancy'+,+'Davolio';SELECT+'</ROOT>'

或

http://IISServer/nwind?sql=SELECT+'<ROOT>';{CALL+FindEmp}+@FName='Nancy'+,+@LName='Davolio';SELECT+'</ROOT>'

请参见

使用 HTTP 访问 SQL Server

使用 FOR XML 检索 XML 文档

使用用于 SQL Server 的 IIS 虚拟目录管理实用工具


使用 HTTP 执行模板文件

在 URL 中写入长 SQL 查询会很麻烦。相反，可使用模板指定查询（SQL 或 XPath）。在 URL 中指定模板文件的名称。模板是包含一个或多个 SQL 语句和 XPath 查询的有效的 XML 文档。

使用模板可以：

  • 指定 SQL 查询或 XPath 查询。在模板中指定 XPath 查询时，模板中还标识在要执行的查询上映射的 XML 数据简化 (XDR) 架构文件。

  • 指定通过执行 SQL 或 Xpath 查询所返回的 XML 片段的顶层元素，从而使在 URL 中执行模板的结果是有效的 XML 文档。

  • 定义可被传递到 SQL 语句或 XPath 查询的参数。

  • 声明命名空间。

  • 指定将应用于所得到的文档的可扩展样式表语言 (XSL) 样式表。

模板文件还可以增强安全性。因为可通过将查询存储在文件（模板文件）中来编辑 URL（并由此编辑 URL中的查询），所以可防止用户修改查询和获得不希望他们看到的信息。

可以通过删除虚拟根上的 URL 查询处理服务，并只允许 Microsoft® SQL Server™ XML ISAPI 处理文件和返回结果集来增强安全性。虚拟根通过用于 SQL Server 的 IIS 虚拟目录管理实用工具注册。

可以在 URL 模板中指定模板之前，必须使用用于 SQL Server 的 IIS 虚拟目录管理实用工具创建 template 类型的虚拟名称。有关更多信息，请参见使用用于 SQL Server 的 IIS 虚拟目录管理实用工具。

请参见

使用用于 SQL Server 的 IIS 虚拟目录管理实用工具

使用 HTTP 访问 SQL Server

使用 FOR XML 检索 XML 文档

使用 XPath 查询


使用 XML 模板

下面是模板的一般形式，显示了指定 SQL 查询和 XPath 查询的方式：

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql"
       sql:xsl='XSL FileName' >
  <sql:header>
    <sql:param>..</sql:param>
    <sql:param>..</sql:param>...n
  </sql:header>
  <sql:query>
    sql statement(s)
  </sql:query>
  <sql:xpath-query mapping-schema="SchemaFileName.xml">
    XPath query
  </sql:xpath-query>
</ROOT>

模板中的任何元素都是可选的。元素 <header>、<param>、<query>、<XPath-query> 和特性映射架构在 sql 命名空间中定义。因此，必须在命名空间中声明 xmlns:sql="urn:schemas-microsoft-com:xml-sql"。可对命名空间任意命名；sql 只是一个别名。

<ROOT>

指定此标记以提供所得到的 XML 文档的单个顶层元素（也称为根标记）。<ROOT> 标记可以是任何名称。

<sql:header>

此标记用于保存所有标题值。在目前的实施方案中，只能在此标记中指定 <sql:param> 元素。<sql:header> 用作包含标记，使您得以定义多个参数。所有的参数定义都在一个位置中，这使得处理参数定义更有效。

<sql:param>

该元素用于定义在模板内传递到查询的参数。每个 <param> 元素定义一个参数。可以在 <sql:header> 标记中定义多个 <param> 元素。

<sql:query>

该元素用于指定 SQL 查询。可以在模板中指定多个 <sql:query> 元素。

<sql:xpath-query>

该元素用于指定 XPath 查询。因为 XPath 查询是在带批注的 XML 数据简化 (XDR) 架构上执行，所以必须使用 mapping-schema 特性指定架构文件名。

sql:xsl

该特性用于指定将应用于所得到的 XML 文档的可扩展样式表语言 (XSL) 样式表。在指定映射架构文件时，可以指定相对或绝对路径。指定的相对路径是相对于与 template 类型的虚拟名称关联的目录。例如，如果与 template 类型的虚拟名称相关联的目录是 C:\Template，那么为 sql:xsl 指定的相对路径 Xyz/MyXSL.xml 将映射到 C:\Template\Xyz\MyXSL.xml。

mapping-schema

该特性用于标识带批注的 XDR 架构。仅当在模板中执行 XPath 查询时才指定该特性。XPath 查询在带批注的 XDR 架构上执行。在指定映射架构文件时，可以指定相对或绝对路径。指定的相对路径是相对于与 template 类型的虚拟名称关联的目录。例如，如果与 template 类型的虚拟名称关联的目录是 C:\Template，则相对路径（为 mapping-schema 指定的 schema/MSchema.xml）映射到 C:\Template\Schema\MSchema.xml。

说明 每个 <sql:query> 或 <sql:XPath-query> 表示单独的事务。因此，如果在模板中有多个 <sql:query> 或 <sql:XPath-query> 标记，当一个标记失败时，其它标记将继续。

如果设置了 contenttype，则 Sqlisapi.dll 将标题信息返回给浏览器。如果没有设置 contenttype，则 urlmon 使用模板文件中的第一个字符确定内容类型。如果模板中的第一个字符是 < 字符或 Unicode 字节顺序标志 (0xFFFE)，则将 text/xml 作为内容类型返回给浏览器，且浏览器显示结果。否则，Sqlisapi.dll 不发送用以指导浏览器如何显示结果的内容类型标题信息；因此，在浏览器中将看不到结果。

可以在 URL 模板中指定模板之前，必须使用用于 SQL Server 的 IIS 虚拟目录管理实用工具创建 template 类型的虚拟名称。有关更多信息，请参见使用用于 SQL Server 的 IIS 虚拟目录管理实用工具。

存储模板

模板存储在与 template 类型的虚拟名称关联的目录或它的一个子目录中：

  • 如果模板存储在与 template 类型的虚拟名称关联的目录中，则 URL 查询的形式如下：
    http://IISServer/nwind/TemplateVirtualName/TemplateFile.xml
  • 如果模板存储在与 template 类型 (xyz) 的虚拟名称关联的子目录中，则 URL 查询的形式如下：
    http://IISServer/nwind/TemplateVirtualName/xyz/TemplateFile.xml

请参见

使用用于 SQL Server 的 IIS 虚拟目录管理实用工具

使用 HTTP 访问 SQL Server

使用 FOR XML 检索 XML 文档

使用 XPath 查询


使用模板执行 SQL 查询

在下列示例中，nwind 是使用用于 SQL Server 的 IIS 虚拟目录管理实用工具创建的虚拟目录，template 是创建虚拟目录时定义的 template 类型的虚拟名称（创建虚拟目录时可以为其指定任何虚拟名称）。有关更多信息，请参见使用用于 SQL Server 的 IIS 虚拟目录管理实用工具。

<sql:query> 标记用于指定 SQL 语句。

示例
A. 创建包含简单 SELECT 语句的模板文件

下面的模板指定简单的 SELECT 语句。

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:query>
    SELECT top 2 CustomerID, CompanyName
    FROM   Customers
    FOR XML AUTO
  </sql:query>
</ROOT>

该模板存储在文件 (File1.xml) 中并通过 URL 执行：

http://IISServer/nwind/template/File1.xml

在模板中指定的查询被其结果所替换。因此，返回的 XML 文档具有与模板本身相同的结构，包括添加的 <ROOT> 标记。

结果如下：

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <Customers CustomerID="ALFKI" CompanyName="Alfreds Futterkiste" />
  <Customers CustomerID="ANATR" CompanyName="Ana Trujillo Emparedados y helados" />
</ROOT>
B. 在模板文件中执行存储过程

也可以在模板中执行存储过程。存储过程也在 <sql:query> 标记中指定。

请考察下面的存储过程：

IF EXISTS (SELECT name FROM sysobjects
   WHERE name = 'CategoryInfo' AND type = 'P')
   DROP PROCEDURE CategoryInfo
GO
CREATE PROCEDURE CategoryInfo
AS
    SELECT   CategoryName
    FROM     Categories
    WHERE    Categories.CategoryID = 2
    FOR XML AUTO

可以在模板中执行存储过程：

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:query>
    exec CategoryInfo
  </sql:query>
</ROOT>

该模板存储在文件 (File1.xml) 中并通过 URL 执行：

http://IISServer/nwind/template/File1.xml

结果如下：

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <Categories CategoryName="Condiments" />
</ROOT>
C. 在模板中使用实体引用

因为模板是 XML 文档，所以必须对特殊字符使用实体引用。下例对特殊标记字符 (>) 使用实体引用 (&gt;)。

请考察下面的模板：

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:query>
      SELECT top 2 *
      FROM     [Order Details]
      WHERE     UnitPrice &gt; 10
      FOR XML AUTO
  </sql:query>
</ROOT>

该模板存储在文件 (File1.xml) 中并通过 URL 执行：

http://IISServer/nwind/template/File1.xml

结果如下：

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <Order_x0020_Details OrderID="10248" ProductID="11" UnitPrice="14"
                       Quantity="12" Discount="0" />
  <Order_x0020_Details OrderID="10248" ProductID="72" UnitPrice="34.8"
                       Quantity="5" Discount="0" />
</ROOT>

如果直接在 URL 中指定该模板，则还需进行进一步的编码。 因为 > 字符在 XML 中是特殊字符，并且因为是在模板（一个 XML 文档）中指定的，所以被编码为 &gt;。而且因为在该 URL 中 & 字符是特殊字符，所以当在 URL 中指定该模板时，必须将 & 编码为 %26。

该模板于是在 URL 中被指定为：

http://IISServer/nwind?template=<ROOT%20xmlns:sql="urn:schemas-microsoft-com:xml-sql"><sql:query>SELECT%20top%202%20*%20FROM%20[Order%20Details]%20WHERE%20UnitPrice%20%26gt;%2010%20FOR%20XML%20AUTO</sql:query></ROOT>
D. 直接在 URL 中指定模板

可以直接在 URL 中指定模板。在下例中，在 URL 中指定包含简单 SELECT 语句的模板：

http://IISServer/nwind?template=<ROOT+xmlns:sql="urn:schemas-microsoft-com:xml-sql"><sql:query>SELECT+*+FROM+Customers+FOR+XML+AUTO</sql:query></ROOT>

注意 出于安全考虑，不建议直接在 URL 中指定模板。

请参见

使用用于 SQL Server 的 IIS 虚拟目录管理实用工具

使用 HTTP 访问 SQL Server

使用 FOR XML 检索 XML 文档


将参数传递到模板

在模板中可以指定要求参数值的 SQL 查询。指定用于定义参数的 <sql:header> 标记。可以为参数指定默认值。如果没有指定参数值便执行模板，则使用默认参数值。

模板也可用于在带批注的 XDR（简化 XML-Data）架构上指定 XPath 查询。<sql:xpath-query> 标记用于指定 XPath 查询。有关更多信息及示例，请参见使用 XPath 查询。

示例

在下列示例中，nwind 是使用用于 SQL Server 的 IIS 虚拟目录管理实用工具创建的虚拟目录，template 是创建虚拟目录时定义的 template 类型的虚拟名称（创建虚拟目录时可以为其指定任何虚拟名称）。有关更多信息，请参见使用用于 SQL Server 的 IIS 虚拟目录管理实用工具。

A. 在模板中指定默认参数

可在模板中为参数值指定默认值。下例中的存储过程需要一个输入参数 (@CategoryName)。

IF EXISTS (SELECT name FROM sysobjects
   WHERE name = 'CategoryInfoWithInputParam' AND type = 'P')
   DROP PROCEDURE CategoryInfoWithInputParam
GO
CREATE PROCEDURE CategoryInfoWithInputParam
                    @CategoryName varchar(35)
AS
    SELECT     CategoryName, Description
    FROM     Categories
    WHERE    Categories.CategoryName = @CategoryName for xml auto

可创建包含用于执行存储过程的调用的模板，如下例所示。该模板为参数 @CategoryName 指定默认值 (Condiments)。

<ROOT xmlns:sql='urn:schemas-microsoft-com:xml-sql'>
  <sql:header>
     <sql:param name='CategoryName'>Condiments</sql:param>
  </sql:header>
  <sql:query >
      exec CategoryInfoWithInputParam @CategoryName
  </sql:query>
</ROOT>

该模板保存在文件 (File1.xml) 中并通过 URL 执行：

http://IISServer/nwind/template/File1.xml

因为没有参数传递到文件，所以使用默认值 (Condiments)。

结果如下：

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <Categories CategoryName="Condiments" Description="Sweet and savory
       sauces, relishes, spreads, and seasonings" />
</ROOT>

也可以直接在 URL 中执行模板：

http://IISServer/nwind?template=<ROOT xmlns:sql='urn:schemas-microsoft-com:xml-sql'><sql:header><sql:param name='CategoryName'>Condiments</sql:param></sql:header><sql:query >exec CategoryInfoWithInputParam @CategoryName</sql:query></ROOT>

注意 出于安全考虑，不建议直接在 URL 中指定查询或模板。

B. 将参数值传递到模板

可以将参数传递到模板文件。在下例中，存储过程需要一个输入参数 (@CategoryName)。

IF EXISTS (SELECT name FROM sysobjects
   WHERE name = 'CategoryInfoWithInputParam' AND type = 'P')
   DROP PROCEDURE CategoryInfoWithInputParam
GO
CREATE PROCEDURE CategoryInfoWithInputParam
                    @CategoryName varchar(35)
AS
    SELECT     CategoryName, Description
    FROM     Categories
    WHERE    Categories.CategoryName = @CategoryName for xml auto

在模板中调用存储过程，如下例所示。该模板为参数 @CategoryName 指定默认值。

<ROOT xmlns:sql='urn:schemas-microsoft-com:xml-sql'>
  <sql:header>
       <sql:param name='CategoryName'>Condiments</sql:param>
  </sql:header>
  <sql:query >
      exec CategoryInfoWithInputParam @CategoryName
  </sql:query>
</ROOT>

该模板存储在文件 (File1.xml) 中并通过 URL 执行：

http://IISServer/nwind/template/File1.xml?CategoryName=Beverages

如果在运行时将参数值传递到文件，则使用指定的值而非默认值。在下面用于执行模板文件的调用中，值 Beverages 被传递到文件。

结果如下：

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
    <Categories CategoryName="Beverages" Description="Soft drinks,
           coffees, teas, beers, and ales" />
</ROOT>

可以直接使用 URL 执行模板：

http://IISServer/nwind?template=<ROOT xmlns:sql='urn:schemas-microsoft-com:xml-sql'><sql:header><sql:param name='CategoryName'>Condiments</sql:param></sql:header><sql:query >exec CategoryInfoWithInputParam @CategoryName</sql:query></ROOT>&CategoryName=Beverages

注意 出于安全考虑，不建议直接在 URL 中指定查询或模板。

C. 将多个参数传递到模板

可以将多个参数传递到模板。在下例中，在 <sql:header> 中指定了两个带默认值的参数。该模板还指定两个需要参数值的查询。

下面的模板由两个 SQL 查询组成，每个查询带一个参数：

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:header>
       <sql:param name='CustomerID'>ALFKI</sql:param>
     <sql:param name='EmployeeID'>1</sql:param>
  </sql:header>
  <sql:query>
     SELECT  CustomerID,CompanyName
     FROM    Customers
     WHERE   CustomerID=@CustomerID
     FOR XML AUTO
  </sql:query>
  <sql:query>
     SELECT EmployeeID,LastName,FirstName
     FROM Employees
     WHERE EmployeeID=@EmployeeID
     FOR XML AUTO
  </sql:query>
</ROOT>

该模板存储在文件 (File1.xml) 中并通过 URL 执行：

http://IISServer/nwind/template/template5.xml

结果如下：

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <Customers CustomerID="ALFKI" CompanyName="Alfreds Futterkiste" />
  <Employees EmployeeID="1" LastName="Davolio" FirstName="Nancy" />
</ROOT>

在下例中，只提供了 CustomerID 参数值。因此，将忽略默认客户 ID 值 ALFKI。没有提供 EmployeeID 参数值，所以使用默认值。

http://IISServer/nwind/template/template5.xml?CustomerID=BERGS

结果如下：

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <Customers CustomerID="BERGS" CompanyName="Berglunds snabbköp" />
  <Employees EmployeeID="1" LastName="Davolio" FirstName="Nancy" />
</ROOT>

通过传递两个参数值执行模板（忽略默认值）。

http://IISServer/nwind/template/template5.xml?CustomerID=BERGS&EmployeeID=2

请参见

使用用于 SQL Server 的 IIS 虚拟目录管理实用工具

使用 HTTP 访问 SQL Server

使用 FOR XML 检索 XML 文档


在模板中指定 XSL 样式表

可以对查询结果应用可扩展样式表语言 (XSL) 样式表。当使用 HTTP 执行模板时，可以用下列方法指定 XSL 文件：

  • 在模板中使用 sql:xsl 特性。

  • 使用 xsl 关键字作为 URL 的一部分，以指定将用于处理所得到的 XML 数据的 XSL 文件。

如果在模板中使用 sql:xsl 指定 XSL 文件并且在 URL 中使用关键字 xsl 指定 XSL 文件，则先对结果应用在模板中指定的 XSL 样式表，然后应用在 URL 中指定的 XSL 文件。

示例

在下列示例中，nwind 是使用用于 SQL Server 的 IIS 虚拟目录管理实用工具创建的虚拟目录，template 是创建虚拟目录时定义的 template 类型的虚拟名称（创建虚拟目录时可以为其指定任何虚拟名称）。有关更多信息，请参见使用用于 SQL Server 的 IIS 虚拟目录管理实用工具。

A. 在模板中指定 sql:xsl 以处理结果

在下例中，模板包含简单的 SELECT 语句。按照使用 sql:xsl 指定的 XSL 文件中的说明处理查询结果。

 <?xml version ='1.0' encoding='UTF-8'?>
 <root xmlns:sql='urn:schemas-microsoft-com:xml-sql'
       sql:xsl='MyXSL.xsl'>
   <sql:query>
      SELECT FirstName, LastName FROM Employees FOR XML AUTO
   </sql:query>
 </root>

为举例说明，将模板 (TemplateWithXSL.xml) 存储在与 template 类型的虚拟名称 (template) 关联的目录中。XSL 文件 (MyXSL.xsl) 也存储在同一目录中。

下面是 XSL 文件：

<?xml version='1.0' encoding='UTF-8'?>
 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <xsl:template match = '*'>
        <xsl:apply-templates />
    </xsl:template>
    <xsl:template match = 'Employees'>
       <TR>
         <TD><xsl:value-of select = '@FirstName' /></TD>
         <TD><B><xsl:value-of select = '@LastName' /></B></TD>
       </TR>
    </xsl:template>
    <xsl:template match = '/'>
      <HTML>
         <HEAD>
           <STYLE>th { background-color: #CCCCCC }</STYLE>
        </HEAD>
        <BODY>
         <TABLE border='1' style='width:300;'>
           <TR><TH colspan='2'>Employees</TH></TR>
           <TR><TH >First name</TH><TH>Last name</TH></TR>
           <xsl:apply-templates select = 'root' />
         </TABLE>
        </BODY>
      </HTML>
    </xsl:template>
</xsl:stylesheet>

下面的 URL 执行模板：

http://IISServer/nwind/template/TemplateWithXSL.xml&contenttype=text/html

因为 XSL 文件应用于结果，所以将 contenttype 设置为 text/html。因此，在 URL 中是否指定 contenttype 参数是可选的。

结果以两列表的格式（FirstName 和 LastName）显示。

还可在 URL 中指定 XSL 文件，而不是在模板中（使用 sql:xsl）指定该文件。在这种情况下，XSL 文件必须存储在与虚拟根 (nwind) 或其子目录关联的目录中，此时必须在 URL 中指定相对路径。假设 XSL 文件存储在与 nwind 虚拟目录关联的目录中，则下面的 URL 执行模板：

http://IISServer/nwind/template/templateFile.xml?xsl=MyXSL.xsl

如果 XSL 文件存储在虚拟根目录的一个子目录 (x) 中，则下面的 URL 这样指定相对路径：

http://IISServer/nwind/template/templateFile.xml?xsl=/x/MyXSL.xsl

如果在模板中使用 sql:xsl 并且在 URL 中使用关键字 xsl 指定 XSL 文件，则在模板中指定的 XSL 样式表首先应用于结果，然后应用在 URL 中指定的 XSL 文件。


使用模板执行 XPath 查询

<sql:xpath-query> 标记用于在模板中指定 XPath 查询。XPath 查询在使用 <xpath-query> 元素的 mapping-schema 特性指定的带批注的 XML 数据简化 (XDR) 映射架构上执行。有关 XDR 架构的更多信息，请参见使用带批注的 XDR 架构创建 XML 视图。有关 XPath 查询的更多信息，请参见使用 XPath 查询。

在模板中指定的映射 XDR 架构必须存储在与（使用用于 SQL Server 的 IIS 虚拟目录管理实用工具创建的）template 虚拟名称关联的目录或它的一个子目录中，在这种情况下必须在 mapping-schema 特性中指定相对路径。

请参见

使用用于 SQL Server 的 IIS 虚拟目录管理实用工具

使用 HTTP 访问 SQL Server

使用带批注的 XDR 架构创建 XML 视图


使用 HTTP 执行 XPath 查询

可以直接在 URL 中指定对带批注的简化 XML-Data (XDR) 架构执行的 XPath 查询。有关 SQL ISAPI 扩展所支持的 URL 语法的更多信息，请参见 URL Access。

带批注的 XDR 架构提供关系数据的 XML 视图。若要对带批注的 XDR 架构执行 XPath 查询，必须将架构文件指定为 URL 的一部分。

若要对带批注的 XDR 架构指定 XPath 查询，必须使用用于 SQL Server 的 IIS 虚拟目录管理实用工具创建 schema 类型的虚拟名称。在 URL 中指定的 XDR 架构必须存储在与 schema 类型的虚拟名称关联的目录或它的一个子目录中：

  • 如果带批注的 XDR 架构存储在与 schema 类型的虚拟名称关联的目录中，则 URL 查询的形式如下：
    http://IISServer/nwind/SchemaVirtualName/XDRSchema.xml/XpathQuery
  • 如果带批注的 XDR 架构存储在与 schema 类型的虚拟名称关联的子目录 (xyz) 中，则 URL 中包含与 schema 类型的虚拟名称关联的目录的相对路径。在这种情况下，URL 查询的形式如下：
    http://IISServer/nwind/SchemaVirtualName/xyz/XDRSchema.xml/XpathQuery
示例

在下例中，nwind 是使用用于 SQL Server 的 IIS 虚拟目录管理实用工具创建的虚拟目录，schema 是在创建虚拟目录时定义的 schema 类型的虚拟名称（创建虚拟目录时可为其指定任何虚拟名称）。

A. 在 URL 中指定 XPath 查询

例如，请考察下面这个带批注的 XDR 架构：

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
        xmlns:dt="urn:schemas-microsoft-com:datatypes"
        xmlns:sql="urn:schemas-microsoft-com:xml-sql">

  <ElementType name="Customer" sql:relation="Customers" >
    <AttributeType name="CustomerID" />
    <AttributeType name="ContactName" />
    <AttributeType name="Phone" />

    <attribute type="CustomerID" />
    <attribute type="ContactName" />
    <attribute type="Phone" />
  </ElementType>
</Schema>

为举例说明，将该 XDR 架构作为 MySchema.xml 存储在与 schema 类型的虚拟名称关联的目录中。

下面的 URL 对在 URL 中指定的 XDR 架构 (MySchema.xml) 执行 XPath 查询。该 XPath 查询请求含有 ALFKI 的 CustomerID 的所有客户。

http://IISServer/nwind/schema/Schema2.xml/Customer[@CustomerID="ALFKI"]

结果如下：

<Customer CustomerID="ALFKI" ContactName="Maria Anders" Phone="030-0074321" />

如果查询返回多个客户，则必须指定 root 关键字以返回有效的 XML 文档。下面的 XPath 查询返回所有客户。在 URL 中指定 root 关键字：

http://IISServer/nwind/schema/Schema2.xml/Customer?root=root

下面是部分结果：

<?xml version="1.0" encoding="utf-8" ?>
<root>
   <Customer CustomerID="ALFKI" ContactName="Maria Anders"
             Phone="030-0074321" />
   <Customer CustomerID="ANATR" ContactName="Ana Trujillo"
             Phone="(5) 555-4729" />
    ...
</root>

请参见

在查询中使用带批注的 XDR 架构

使用 XPath 查询

使用带批注的 XDR 架构创建 XML 视图


使用 HTTP 访问数据库对象

可以直接使用 URL 访问数据库对象（如表和视图）。在这种情况下，直接对数据库对象指定 XPath 查询以获得结果（一行/一列值）。有关 SQL ISAPI 扩展所支持的 URL 语法的更多信息，请参见 URL Access。

在 URL 中，dbobject 类型的虚拟名称是在直接访问数据库对象时指定的。

FOR XML 查询可返回对二进制数据的引用。可以通过发送另一个含有 dbobject 引用的 URL 查询来检索与该引用关联的二进制数据。这是 dbobject 虚拟名称类型的主要用途。有关使用 FOR XML 的查询的更多信息，请参见使用 FOR XML 检索 XML 文档。

示例

在以下示例中，nwind 是用用于 SQL Server 的 IIS 虚拟目录管理实用工具创建的虚拟目录。dbobject 是 dbobject 类型的虚拟名称，template 是 template 类型的虚拟名称，这两个名称都是在创建虚拟目录时定义的（在创建虚拟名称时可为其提供任何名称）。有关更多信息，请参见使用用于 SQL Server 的 IIS 虚拟目录管理实用工具。

A. 在 URL 中使用 dbobject 类型的虚拟名称检索职员的照片

指定的 XPath 查询从 Employees 表中检索 Photo 列。在下面的 URL 中，Employees[@EmployeeID='1']/@Photo 是 XPath 查询。在该查询中，Employees 是表名，@EmployeeID='1' 是谓词，用于查找 ID 值为 1 的职员。@Photo 是从中检索值的列。

http://IISServer/nwind/dbobject/Employees[@EmployeeID='1']/@Photo

该查询被转换为下面的 SELECT 语句：

SELECT    Photo
FROM       Employees
WHERE    EmployeeID='1'

说明 XPath 查询必须对单行和单列进行标识。

B. 执行查询以获得对图像数据的引用并应用 XSL 样式表处理该引用

在下例中，指定 SELECT 语句检索职员的 ID 和照片。该查询返回对图像数据的引用。这些引用由可扩展样式表语言 (XSL) 文件用于检索职员的照片并在浏览器中显示这些照片。

在模板中指定该查询。为举例说明，将模板文件作为 TemplateWithAnXSL.xml 文件保存在虚拟根的 template 子目录中（假定该目录是在创建 template 类型的虚拟名称时指定的目录）。

<?xml version ='1.0' encoding='UTF-8'?>
<root xmlns:sql='urn:schemas-microsoft-com:xml-sql' sql:xsl='photo.xsl'>
  <sql:query >
     SELECT employeeID, photo FROM employees FOR XML AUTO
  </sql:query>
</root>

下面是用于处理结果集的 XSL 文件 (Photo.xsl)。为举例说明，将该文件存储在虚拟根目录中。

<?xml version='1.0' encoding='UTF-8'?>
 <xsl:stylesheet xmlns:xsl='http://www.w3.org/TR/WD-xsl' >
    <xsl:template match = '*'>
        <xsl:apply-templates />
    </xsl:template>
    <xsl:template match = 'employees'>
       <TR>
         <TD><xsl:value-of select = '@employeeID' /></TD>
         <TD><B> <IMG><xsl:attribute name='src'>
                    <xsl:value-of select = '@photo'/>
                    </xsl:attribute>
                 </IMG>
         </B></TD>
       </TR>
    </xsl:template>
    <xsl:template match = '/'>
      <HTML>
        <HEAD>
           <STYLE>th { background-color: #CCCCCC }</STYLE>
        <!-- <BASE href='http://IISServer/nwind/'></BASE>    -->
        </HEAD>
        <BODY>
         <TABLE border='1' style='width:300;'>
           <TR><TH colspan='2'>Employees</TH></TR>
           <TR><TH >EmployeeID</TH><TH>Photo</TH></TR>
           <xsl:apply-templates select = 'root' />
         </TABLE>
        </BODY>
      </HTML>
    </xsl:template>
</xsl:stylesheet>

下面的 URL 执行模板：

http://IISServer/nwind/template/TemplatewithAnXSL.xml?contenttype=text/html

在应用 XSL 文件后，查询结果显示为含有两列的表（EmployeeID 和 Photo）。

C. 在查询中指定特殊字符

在 URL 中，问号 (?) 分隔 URL 和传递到 URL 的参数。任何特殊字符，如 ? 右侧的加号 (+)，都将被浏览器进行转义（即，将 ? 右侧的 + 转换成 %20）。

在下例中，谓词表达式中的 + 被解释为加法运算符（因为 URL 中没有 ?），所以 URL 生成错误。在 URL 中必须指定 %20 代替 +。

http://IISServer/nwind/dbobject/Orders[@OrderID=10248%20and%20@EmployeeID=5]/@CustomerID

请参见

使用用于 SQL Server 的 IIS 虚拟目录管理实用工具

使用 XPath 查询


用以发布模板的示例应用程序

本节的主题展示了一些简单的应用程序，用以显示如何发布模板。


使用 HTML 窗体发布模板

HTML 窗体可用于发布模板。HTML 窗体的输入机制可用于获得用户为可传递到 SQL 语句的参数输入的值。在 HTML 窗体的 TEXTAREA 元素中，template 用作 NAME 特性的变量名。TEXTAREA 的正文于是作为 template 的值发送。

示例

在以下示例中，nwind 是用用于 SQL Server 的 IIS 虚拟目录管理实用工具创建的虚拟目录（在创建虚拟名称时可为其提供任何名称）。有关更多信息，请参见使用用于 SQL Server 的 IIS 虚拟目录管理实用工具。

A. 在窗体中发布简单模板

在下例中，HTML 窗体提示用户输入职员 ID。在模板中该 ID 值用作 SELECT 语句的输入参数。该查询从 Northwind 数据库的 Employees 表中返回职员的名字和姓氏。下面的窗体可保存在 .htm 文件中并可在浏览器中打开。

<head>
<TITLE>Sample Form </TITLE>
</head>
<body>
For a given employee ID, employee first and last name is retrieved.
<form action="http://IISServer/nwind" method="POST">
<B>Employee ID Number</B>
<input type=text name=EmployeeID value='1'>
<input type=hidden name=contenttype value=text/xml>
<input type=hidden name=template value='
<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql" >
<sql:header>
    <sql:param name="EmployeeID">1</sql:param>
</sql:header>
<sql:query>
  SELECT FirstName, LastName
  FROM    Employees
  WHERE    EmployeeID=@EmployeeID
  FOR XML AUTO
</sql:query>
</ROOT>
'>
<p><input type="submit">
</form>
</body>
B. 在 HTML 窗体中发布模板并提供 XSL 文件以处理输出

在下例中，使用一个简单的 HTML 窗体发布模板。该模板包含从 Northwind 数据库的 Employees 表中返回名字和姓氏的 SELECT 语句。

当在浏览器中打开该 HTML 文档时，用户可以指定内容类型和用于处理结果集的可扩展样式表语言 (XSL) 文件。如果将内容类型指定为 text/html，则 XSL 文件处理结果集并生成包含两列的表作为结果输出。

如果将内容类型指定为 text/xml，则以 XML 文档的形式显示结果。

说明 XSL 文件必须驻留在与虚拟目录关联的物理目录（或它的一个子目录）中。如果文件存储在该物理目录中，则只需指定文件名。如果文件存储在该物理目录的一个子目录中，则须指定该物理目录的相对路径。

<body>

Hi there

<form action="http://IISServer/nwind" method="POST">

contenttype

<input name=contenttype value="text/html">

<br>

xsl

<input name=xsl value="emp.xsl"><br>

<input type=hidden name=template value='

<ROOT>

<sql:query xmlns:sql="urn:schemas-microsoft-com:xml-sql">

Select FirstName, LastName from Employees for xml auto</sql:query>

</ROOT>

'>

<p><input type="submit">

</form>

</body>

下面提供 XSL 文件。对结果集应用 XSL 转换。

<?xml version="1.0"  encoding="ISO-8859-1" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">
<xsl:template match = "*">
   <xsl:apply-templates />
</xsl:template>

<xsl:template match = "Employees">
   <TR>
   <TD><xsl:value-of select = "@FirstName" /></TD>
   <TD><B><xsl:value-of select = "@LastName" /></B></TD>
   </TR>
</xsl:template>

<xsl:template match = "/">
    <HTML>
    <HEAD>
    <STYLE>th { background-color: #CCCCCC }</STYLE>
    </HEAD>
    <BODY>
   <TABLE border="1" style="width:300;">
   <TR><TH colspan="2">Employees</TH></TR>
   <TR><TH >FirstName</TH><TH>LastName</TH></TR>
   <xsl:apply-templates select = "ROOT" />
   </TABLE>
    </BODY>
    </HTML>
</xsl:template>
</xsl:stylesheet>

请参见

使用用于 SQL Server 的 IIS 虚拟目录管理实用工具

使用 HTTP 访问 SQL Server

使用 FOR XML 检索 XML 文档

使用 XPath 查询


直接将模板发布到虚拟目录

该 Microsoft® Visual Basic® 示例显示在不使用 Web 浏览器时如何将模板直接发送到虚拟目录。在该示例中，将一个由 SELECT 语句组成的模板直接发送到 nwind 虚拟目录。有关如何创建 nwind 虚拟目录的信息，请参见创建 nwind 虚拟目录。

  Dim xmlHttp As New MSXML2.xmlHttp
  Dim doc As New MSXML2.DOMDocument
  Dim strQuery As String
  Dim strURL As String
  Dim strPostBody As String

   ' Set the post body - this is the query/request.
  strPostBody = "<?xml version='1.0' encoding='UTF-16'?>                   " & _
                "<root>                                                    " & _
                "<sql:query xmlns:sql='urn:schemas-microsoft-com:xml-sql'> " & _
                " select OrderID, shipName from Orders for xml raw                                   " & _
                "</sql:query>                                              " & _
                "</root>                                                   "

   ' Validate the document using the MSXML parser.
  doc.loadXML strPostBody

  If doc.parseError.errorCode Then
' Do something with the error.
  End If

   ' Post the template.
  xmlHttp.Open "POST", "http://localhost/nwind", False
  xmlHttp.setRequestHeader "Content-type", "application/xml"
  xmlHttp.send doc

   ' Retrieve the results.
   Debug.Print xmlHttp.responseText

请参见

使用用于 SQL Server 的 IIS 虚拟目录管理实用工具

使用 HTTP 访问 SQL Server

使用 FOR XML 检索 XML 文档

使用 XPath 查询


使用带批注的 XDR 架构创建 XML 视图

可以使用 XDR（简化 XML-Data）架构创建关系数据的 XML 视图。然后可以使用 XPath 查询来查询这些视图。这类似于使用 CREATE VIEW 语句创建视图并指定对视图的 SQL 查询。

XML 架构描述 XML 文档的结构以及对文档中数据的不同约束。当指定对该架构的 XPath 查询时，返回的 XML 文档结构由对其执行 XPath 查询的架构确定。

在 Microsoft® SQL Server™ 2000 中，使用简化 XML-Data (XDR) 语言创建架构。XDR 是一种灵活的语言，它克服了用来描述文档结构的文档类型定义 (DTD) 的一些限制。与 DTD 不同，XDR 架构使用与 XML 文档相同的语法描述文档结构。 此外，在 DTD 中，所有数据内容均为字符数据。XDR 语言架构使您得以指定元素或特性的数据类型。

在 XDR 架构中，<Schema> 元素包含整个架构。作为 <Schema> 元素的属性，可以描述定义架构名称的特性和架构驻留的命名空间。在 XDR 语言中，所有元素声明都必须包含在 <Schema> 元素中。

最小的 XDR 架构如下：

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data">
   ...
</Schema>

<Schema> 元素是从 xml-data 命名空间 (urn:schemas-microsoft-com:xml-data) 派生出的。

说明 本文档假设您熟悉 XML-Data 语言。

XDR 架构的批注

可以在 XDR 架构中使用对到数据库的映射进行描述的批注来查询该数据库，并以 XML 文档格式返回结果。SQL Server 2000 引入了许多批注，可以使用这些批注将 XDR 架构映射到数据库中的表和列。可以对 XDR 架构所创建的 XML 视图指定 XPath 查询，以查询数据库并获得 XML 格式的结果。

这是替代更复杂的 SQL 查询编写过程的方法，该方法使用 FOR XML EXPLICIT 模式将 XML 文档结构作为查询的一部分加以描述。有关在 SELECT 查询中使用 FOR XML EXPLICIT 模式的更多信息，请参见使用 EXPLICIT 模式。然而，为克服对映射架构上的 XPath 查询的大多数限制，请使用 FOR XML EXPLICIT 模式的 SQL 查询返回 XML 文档格式的结果。

如果拥有公用 XDR 架构（如 Microsoft BizTalk™ 架构），可以执行下列任一操作：

  • 编写 FOR XML EXPLICIT 模式的查询，以便生成的数据对公用 XDR 架构有效；然而，编写 FOR XML EXPLICIT 查询可能比较麻烦。

  • 制作公用 XDR 架构的专用复本。然后将批注添加到专用复本，从而生成映射架构。可以指定对映射架构的 XPath 查询。该查询所生成的是公用架构命名空间中的数据。与编写复杂的 FOR XML EXPLICIT 查询相比，创建带批注的架构并指定对该架构的 XPath 查询是一个简单得多的过程。下图说明了此过程。

说明 Microsoft BizTalk™ 框架旨在为常用商业对象（如合同、订单和约会）定义标准 XML 格式。这些商业架构复本可以在 http://biztalk.org/BizTalk/default.asp 中找到。

映射架构

在关系数据库的上下文中，将任意的 XDR 架构映射到关系存储是非常有用的。达到此目的的一个方法是对 XDR 架构进行批注。带批注的 XDR 架构称为"映射架构"，它提供了关于如何将 XML 数据映射到关系存储的信息。映射架构实际上是关系数据的 XML 视图。可以使用这些映射检索 XML 文档格式的关系数据。

Microsoft SQL Server 2000 引入了许多批注，可以在 XDR 架构中使用这些批注，将元素和特性映射到数据库表和列。可以使用 XPath（XML 路径）指定对映射架构（XML 视图）的查询。映射架构描述了最后所得到的文档结构。

批注的命名空间

在 XDR 架构中，使用下面的命名空间指定批注：urn:schemas-microsoft-com:xml-sql。

下例显示指定命名空间的最简单方法是在 <Schema> 标记中指定它。urn:schemas-microsoft-com:xml-sql 命名空间的批注必须是由命名空间限定的。

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
        xmlns:sql="urn:schemas-microsoft-com:xml-sql"
               >
    ...........
</Schema>

所用的命名空间前缀是任意的。 在本文档中，sql 前缀用于表示批注命名空间和使此命名空间中的批注区别于其它命名空间中的批注。

数据类型的命名空间

XDR 架构使您得以指定元素或特性的数据类型。使用下面的命名空间指定数据类型： urn:schemas-microsoft-com:datatypes。

以下是带有命名空间声明的最小 XDR 架构：

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
        xmlns:sql="urn:schemas-microsoft-com:xml-sql"
        xmlns:dt="urn:schemas-microsoft-com:datatypes">
   ...
</Schema>

所用的命名空间前缀是任意的。 在本文档中，dt 前缀用于表示数据类型命名空间和使此命名空间中的批注区别于其它命名空间中的批注。

<Schema> 元素来源于 xml-data 命名空间：urn:schemas-microsoft-com:xml-data。

XDR 架构示例

下例显示如何将批注添加到 XDR 架构中。XDR 架构由 <Employee> 元素和 EmpID、Fname 及 Lname 特性组成。

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
        xmlns:dt="urn:schemas-microsoft-com:datatypes"
        xmlns:sql="urn:schemas-microsoft-com:xml-sql">

<ElementType name="Employee" >
    <AttributeType name="EmpID" />
    <AttributeType name="FName" />
    <AttributeType name="LName" />

    <attribute type="EmpID" />
    <attribute type="FName" />
    <attribute type="LName" />
</ElementType>
</Schema>

现在，将批注添加到此 XDR 架构中，使架构的元素和特性映射到数据库的表和列。 带批注的 XDR 架构如下：

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
        xmlns:dt="urn:schemas-microsoft-com:datatypes"
        xmlns:sql="urn:schemas-microsoft-com:xml-sql">

<ElementType name="Employee" sql:relation="Employees" >
    <AttributeType name="EmpID" />
    <AttributeType name="FName" />
    <AttributeType name="LName" />

    <attribute type="EmpID" sql:field="EmployeeID" />
    <attribute type="FName" sql:field="FirstName" />
    <attribute type="LName" sql:field="LastName" />
</ElementType>
</Schema>

在此映射架构中，使用 sql:relation 批注将 <Employee> 元素映射到 Employees 表。使用 sql:field 批注将特性 EmpID、Fname 和 Lname 映射到 Employees 表中的 EmployeeID、FirstName 和 LastName 列。

此带批注的 XDR 架构提供关系数据的 XML 视图。使用 Xpath（XML 路径）语言可以查询该 XML 视图。Xpath 查询返回 XML 文档形式的结果，而不是 SQL 查询所返回的行集。

说明 在映射架构中，指定的关系值（如表名和列名）区分大小写。


XDR 架构的批注

Microsoft® SQL Server™ 2000 在 XDR 架构语言中引入了许多批注。可以在 XDR 架构内使用这些批注指定 XML 到关系的映射。这包括 XDR 架构中的元素和特性到数据库中的表/视图和列之间的映射。默认情况下，带批注的架构中的元素名映射到指定数据库中的表（视图）名，而特性名映射到列名。还可以使用这些批注指定 XML 中的层次结构关系（由此表示数据库中的关系）。

下表显示批注列表。

批注 | 描述 | 主题链接
sql:relation | 将 XML 项目映射到数据库表。 | 使用 sql:relation
sql:field | 映射 XML 项目和数据库列。 | 使用 sql:field
sql:is-constant | 创建不映射到任何表的 XML 元素。 该元素出现在查询输出中。 | 使用 sql:is-constant 创建常量元素
sql:map-field | 允许从结果中排除架构项目。 | 使用 sql:map-field 从所得到的 XML 文档中排除架构元素
<sql:relationship> | 指定 XML 元素间的关系。 key、key-relation、foreign-key 和 foreign-relation 特性用于建立关系。 | 使用 <sql:relationship> 指定关系
sql:limit-field sql:limit-value | 允许基于限制值限制所返回的值。 | 使用 sql:limit-field 和 sql:limit-value 筛选值
sql:key-fields | 允许唯一标识表中行的列规范。 | 使用 sql:key-fields 标识键列
sql:target-namespace | 允许对于查询结果将来自默认命名空间的元素和特性放入其它命名空间。 | 使用 sql:target-namespace 指定目标命名空间
sql:id-prefix | 创建有效的 XML ID、IDREF 和 IDREFS。 用 ID、IDREF 和 IDREFS 的值预先准备字符串。 | 使用 sql:id-prefix 创建有效的ID、IDREF 和 IDREFS 类型特性
sql:use-cdata | 允许指定 CDATA 部分用于 XML 文档中的特定元素。 | 使用 sql:use-cdata 创建 CDATA 节
sql:url-encode | 当 XML 元素/特性映射到一个 SQL Server BLOB 列时，允许请求返回以后可用于 BLOB 数据的引用 (URI)。 | 使用 sql:url-encode 请求对 BLOB 数据的 URL 引用
sql:overflow-field | 标识包含溢出数据的数据库列。 | 使用 sql:overflow-field 检索未用完的数据

说明 本节主题给出的所有示例指定在每个示例中描述的带批注 XDR 架构上执行的简单 XPath 查询。 事先假设您熟悉 XPath 语言。有关更多信息，请参见使用 Xpath 查询。

请参见

用于 SQL Server 的 IIS 虚拟目录管理

使用 XPath 查询

使用 HTTP 访问 SQL Server

使用 HTTP 执行模板文件


XDR 元素和特性到表和列的默认映射

在带批注的 XDR 架构中，默认情况下，<element> 映射到同名的表/视图，而特性映射到同名的列。

可将架构中不复杂的子元素映射到数据库列。若要将 <element> 映射到数据库列，应为该元素指定 content 特性，特性值为 textOnly。如果在将 <element> 映射到数据库列的过程中未指定 content=textOnly，则必须显式指定 sql:field 批注才能将 <element> 映射到数据库列。有关更多信息，请参见使用 sql:field。

示例

若要使用这些示例创建工作示例，必须创建 nwind 虚拟目录（以访问 Northwind 数据库）和 template 类型的虚拟名称。有关创建 nwind 虚拟目录的更多信息，请参见创建 nwind 虚拟目录。

在每一示例中创建工作示例时，可使用模板在映射 XDR 架构上指定 XPath 查询。在查询中使用带批注的 XDR 架构有不同的方法，如内嵌架构和 URL 中的架构。有关更多信息，请参见在查询中使用带批注的 XDR 架构。

A. 指定默认映射

在本例中，<Employees> 元素映射到 Northwind 数据库的 Employees 表，而所有特性映射到 Employees 表的同名列。在该 XDR 架构中，未指定批注。

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
        xmlns:dt="urn:schemas-microsoft-com:datatypes"
        xmlns:sql="urn:schemas-microsoft-com:xml-sql">

<ElementType name="Employees" >
    <AttributeType name="EmployeeID" />
    <AttributeType name="FirstName" />
    <AttributeType name="LastName" />

    <attribute type="EmployeeID" />
    <attribute type="FirstName" />
    <attribute type="LastName" />
</ElementType>
</Schema>

在架构上测试示例 XPath 查询

  1. 将架构 (MySchema.xml) 保存在与已经创建的 template 虚拟名称相关联的目录中（或其中一个子目录中，在此情况下必须在 mapping-schema 特性中指定相对路径）。

  2. 创建下面的模板 (MySchemaT.xml) 并将其保存在与 template 虚拟名称相关联的目录中：
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
    <sql:xpath-query mapping-schema="MySchema.xml">
        /Employees
    </sql:xpath-query>
</ROOT>

    为映射架构 (MySchema.xml) 指定的目录路径相对于与 template 虚拟名称相关联的目录。还可指定绝对路径，例如：

    mapping-schema="C:\MyDir\MySchema.xml"
  3. 下面的 URL 执行模板：
    http://IISServer/VirtualRoot/template/MySchemaT.xml
  4. 下面是部分结果集：
    <?xml version="1.0" encoding="UTF-8" ?>
<ROOT>
  <Employees EID="1" FirstName="Nancy" LastName="Davolio"></Employee>
  <Employees EID="2" FirstName="Andrew" LastName="Fuller"></Employee>
</ROOT>
B. 将 XML <element> 映射到数据库列

默认情况下，XML <element> 映射到数据库表，而 <attribute> 映射到数据库列。若要将 <element> 映射到数据库列，需为 content 特性指定 textOnly 值。

此 XDR 架构由带有子元素<FirstName> 和 <LastName> 以及 EmployeeID 特性的 <Employees> 元素组成。

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
        xmlns:dt="urn:schemas-microsoft-com:datatypes"
        xmlns:sql="urn:schemas-microsoft-com:xml-sql">

<ElementType name="FirstName" content="textOnly" />
<ElementType name="LastName"  content="textOnly" />

<ElementType name="Employees" >
    <AttributeType name="EmployeeID" />

    <attribute type="EmployeeID" />
    <element type="FirstName" />
    <element type="LastName"  />
</ElementType>
</Schema>

默认情况下，XDR 架构中的 <Employees> 元素映射到数据库的 Employees 表。content 特性在 <FirstName> 和 <LastName> 子元素中指定。 因此，这些子元素将映射到 Employees 表中的同名列。

说明 不支持混合的内容（元素同时带有文本和子元素)。

在架构上测试示例 XPath 查询

  1. 将架构 (MySchema.xml) 保存在与已经创建的 template 虚拟名称相关联的目录中（或其中一个子目录中，在此情况下必须在 mapping-schema 特性中指定相对路径）。

  2. 创建下面的模板 (MySchemaT.xml) 并将其保存在与 template 虚拟名称相关联的目录中：
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
    <sql:xpath-query mapping-schema="MySchema.xml">
        /Employees
    </sql:xpath-query>
</ROOT>

    为映射架构指定的目录路径相对于与 template 虚拟名称相关联的目录。还可指定绝对路径，例如：

    mapping-schema="C:\MyDir\MySchema.xml"
  3. 下面的 URL 执行模板：
    http://IISServer/VirtualRoot/template/MySchemaT.xml
  4. 下面是部分结果集：
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <Employees EmployeeID="1">
    <FirstName>Nancy</FirstName>
    <LastName>Davolio</LastName>
  </Employees>
</ROOT>

请参见

用于 SQL Server 的 IIS 虚拟目录管理

使用 XPath 查询

使用 HTTP 访问 SQL Server

使用 HTTP 执行模板文件


XDR 元素和特性到表和列的显式映射

通过 XDR 架构提供关系数据库的 XML 视图时，架构中的元素和特性必须映射到数据库的表和列。数据库表/视图中的行将映射到 XML 中的元素。数据库中的列值映射到特性或元素。若要从数据库中获得单个值，在映射 XDR 架构中指定的映射必须既指定关系又指定字段。

默认情况下，带批注架构中的元素名映射到指定数据库中的表（视图）名。如果元素/特性名与数据库中的表（视图）/列名相同，则不需要显式指定任何映射。

然而，如果元素/特性名与数据库中的表（视图）/列名不同，则使用下列批注指定 XML 文档中的元素/特性与数据库中的表/列之间的映射。

sql:relation

将 XML 元素映射到数据库表。

sql:field

将特性或不复杂的子元素映射到数据库列。

在带批注的 XDR 架构上指定 XPath 查询时，从相应的映射表和列中检索元素和特性数据。

请参见

XDR 元素和特性到表和列的默认映射


使用 sql:relation

添加 sql:relation 批注以将 XDR 架构中的XML 节点映射到数据库表。指定表/视图名称作为 sql:relation 批注的值。

sql:relation 批注可以添加到 XDR架构中的 <ElementType>、<element> 或 <attribute> 节点上。sql:relation 指定架构中的 <ElementType>、<element> 或 <attribute> 与数据库中的表（视图）之间的映射。

当在 <ElementType> 上指定 sql:relation 时，批注的作用域包括 <ElementType> 中的所有特性和子元素规范。因此，它提供了编写批注的快捷方式。当直接在 <element> 上指定 sql:relation 时，也将作用域引入 <ElementType> 内指定的特性，<AttributeType> 上忽略 sql:relation。

标识符在 Microsoft® SQL Server™ 中有效而在 XML 中无效的情况下，sql:relation 有用。例如，Order Details 在 SQL Server 中为有效表名而在 XML 中却无效。 在此情况下，sql:relation 批注可用于指定映射，例如：

<ElementType name="OD" sql:relation="[Order Details]">
示例

若要使用这些示例创建工作示例，必须创建 nwind 虚拟目录（以访问 Northwind 数据库）和 template 类型的虚拟名称。 有关创建 nwind 虚拟目录的更多信息，请参见创建 nwind 虚拟目录。

在每一示例中创建工作示例时，使用模板在映射 XDR 架构上指定 XPath 查询。在查询中使用带批注的 XDR 架构有不同的方法，如内嵌架构和 URL 中的架构 。有关更多信息，请参见在查询中使用带批注的 XDR 架构。

在包含特性的 <ElementType> 上指定 sql:relation

本例中，XDR 架构由带有 CustomerID、ContactName 和 Phone 特性的 <Customer> 元素组成。 在 <ElementType> 上指定 sql:relation 批注，将 Customer 元素映射到 Customers 表。 该映射的作用域包括 <ElementType> 中的所有特性。 因此，所有特性都映射到 Customers 表中的列。

发生特性的默认映射，例如，特性映射到 Customers 表中的同名列。

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
        xmlns:dt="urn:schemas-microsoft-com:datatypes"
        xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <ElementType name="Customer" sql:relation="Customers" >
    <AttributeType name="CustomerID" />
    <AttributeType name="ContactName" />
    <AttributeType name="Phone" />

    <attribute type="CustomerID" />
    <attribute type="ContactName" />
    <attribute type="Phone" />
  </ElementType>
</Schema>

在架构上测试示例 XPath 查询

  1. 将架构 (MySchema.xml) 保存在与已经创建的 template 虚拟名称相关联的目录中（或其中一个子目录中，在此情况下必须在 mapping-schema 特性中指定相对路径）。

  2. 创建下面的模板 (MySchemaT.xml) 并将其保存在与 template 虚拟名称相关联的目录中。此模板中的查询选择 CustomerID 为 ALFKI 的客户。
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:xpath-query mapping-schema="MySchema.xml">
    /Customer[@CustomerID="ALFKI"]
  </sql:xpath-query>
</ROOT>

    为映射架构指定的目录路径相对于与 template 虚拟名称相关联的目录。还可指定绝对路径，例如：

    mapping-schema="C:\MyDir\MySchema.xml"
  3. 下面的 URL 执行模板：
    http://IISServer/VirtualRoot/template/MySchemaT.xml
  4. 下面是部分结果集：
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
    <Customer CustomerID="ALFKI" ContactName="Maria Anders"
              Phone="030-0074321" />
</ROOT>

B. 在包含子元素和特性的 <ElementType> 上指定 sql:relation

本例中，XDR 架构由带有 CustomerID、ContactName 特性和 <Address> 子元素的 <Customer> 元素组成。在 <ElementType> 上指定 sql:relation 批注，将 Customer 元素映射到Customers 表。该映射的作用域包括 <ElementType> 中的所有特性。因此，所有特性映射到 Customers 表中的列。

发生特性的默认映射。特性映射到 Customers 表中的同名列。

本例中，在 <Address> 子元素上指定 content 特性。若无 content=textOnly 特性，则由于在默认情况下，元素映射到表而不是字段，因此，<Address> 元素不映射到 Customers 表中的 address 列。

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
        xmlns:dt="urn:schemas-microsoft-com:datatypes"
        xmlns:sql="urn:schemas-microsoft-com:xml-sql">

  <ElementType name="Address" content="textOnly"  />
  <ElementType name="Customer" sql:relation="Customers" >
    <AttributeType name="CustomerID" />
    <AttributeType name="ContactName" />

    <attribute type="CustomerID" />
    <attribute type="ContactName" />
    <element type="Address"  />
  </ElementType>
</Schema>

或者，可以不指定 content=textOnly 特性，而是指定 sql:field 批注将 <Address> 子元素映射到 Address 列：

<element type="Address" sql:field="Address" >

在架构上测试示例 XPath 查询

  1. 将架构 (MySchema.xml) 保存在与已经创建的 template 虚拟名称相关联的目录中（或其中一个子目录中，在此情况下必须在 mapping-schema 特性中指定相对路径）。

    2.

  2. 创建下面的模板 (MySchemaT.xml) 并将其保存在与 template 虚拟名称相关联的目录中。此模板中的查询选择 CustomerID 为 ALFKI 的客户。

    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:xpath-query mapping-schema="MySchema.xml">
    /Customer[@CustomerID="ALFKI"]
  </sql:xpath-query>
</ROOT>

    为映射架构指定的目录路径相对于与 template 虚拟名称相关联的目录。还可指定绝对路径，例如：

    mapping-schema="C:\MyDir\MySchema.xml"

    3.

  3. 下面的 URL 执行模板：

    http://IISServer/VirtualRoot/template/MySchemaT.xml

    4.

  4. 下面是部分结果集：

    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <Customer CustomerID="ALFKI" ContactName="Maria Anders">
    <Address>Obere Str. 57</Address>
  </Customer>
</ROOT>

    5.

请参见

用于 SQL Server 的 IIS 虚拟目录管理

使用 XPath 查询

使用 HTTP 访问 SQL Server

使用 HTTP 执行模板文件


使用 sql:field

sql:field 批注指定带批注架构中的元素或特性与数据库中的列之间的映射。可以将 sql:field 添加到元素或特性。在带批注架构的 <AttributeType> 元素上忽略 sql:field。sql:field 特性指定表或视图中的映射列的名称。

例如，当列名与 XDR 中指定的架构内的字段不匹配时，可以使用 sql:field 指定名称。 sql:field 的值必须为列名。不允许四部分列名，如 database.owner.table.columnname。此规定适用于所有将列名作为值的批注。

示例

若要使用这些示例创建工作示例，必须创建 nwind 虚拟目录（以访问 Northwind 数据库）和 template 类型的虚拟名称。有关创建 nwind 虚拟目录的更多信息，请参见创建 nwind 虚拟目录。

在每一示例中创建工作示例时，使用模板在映射 XDR 架构上指定 XPath 查询。在查询中使用带批注的 XDR 架构有不同的方法，如内嵌架构和 URL 中的架构。有关更多信息，请参见在查询中使用带批注的 XDR 架构。

A. 为 XDR 架构中的 <attribute> 指定 sql:field

在下面的批注架构中，在架构的 <attribute> 元素上指定 sql:field 批注。sql:field 特性将架构中的 Company 特性映射到 Customers 表中的 CompanyName 列。

因为 XDR 架构中的特性名 CustomerID 与 Customers 表中的 CustomerID 列相同，所以不指定 sql:field。下面是默认情况下的映射。

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
        xmlns:dt="urn:schemas-microsoft-com:datatypes"
        xmlns:sql="urn:schemas-microsoft-com:xml-sql">

<ElementType name="Customer" sql:relation="Customers" >
    <AttributeType name="CustomerID" />
    <AttributeType name="Company" />

    <attribute type="CustomerID" />
    <attribute type="Company" sql:field="CompanyName" />
</ElementType>
</Schema>

在架构上测试示例 XPath 查询

  1. 将架构 (MySchema.xml) 保存在与已经创建的 template 虚拟名称相关联的目录中（或其中一个子目录中，在此情况下必须在 mapping-schema 特性中指定相对路径）。

  2. 创建下面的模板 (MySchemaT.xml) 并将其保存在与 template 虚拟名称相关联的目录中。此模板中的查询选择 CustomerID 为 ALFKI 的客户。
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:xpath-query mapping-schema="MySchema.xml">
    /Customer[@CustomerID="ALFKI"]
  </sql:xpath-query>
</ROOT>
  3. 下面的 URL 执行模板：
    http://IISServer/VirtualRoot/template/MySchemaT.xml
  4. 下面是部分结果集：
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <Customer CustomerID="ALFKI" Company="Alfreds Futterkiste" />
</ROOT>

在映射架构中，可以全局声明特性（例如，在 <ElementType> 作用域的外部声明 <AttributeType...>），然后如下面的架构所示在 <attribute type=...> 中引用特性。

在下面的架构中，全局声明 Contact 特性并在 Customer <ElementType> 作用域中引用它。

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
        xmlns:dt="urn:schemas-microsoft-com:datatypes"
        xmlns:sql="urn:schemas-microsoft-com:xml-sql">

<AttributeType name="Contact" />

<ElementType name="Customer" sql:relation="Customers" >
    <AttributeType name="CustomerID" />
    <AttributeType name="Company" />

    <attribute type="CustomerID" />
    <attribute type="Company" sql:field="CompanyName" />
    <attribute type="Contact" sql:field="ContactName" />
</ElementType>
</Schema>
B. 为 XDR 架构中的 <element> 指定 sql:fieldin

在下面的批注架构中，在架构的 <element> 上指定 sql:field 批注。sql:field 批注将架构中的 <CompanyName> 子元素映射到 Customers 表中的 CompanyName 列。

在没有显式批注的情况下，架构中 <Customers> 元素的 <CompanyName> 子元素将不会映射到 Customers 表的 CompanyName 列，因为元素默认映射到关系，而不是映射到字段（当 <ElementType> 包含 textOnly 特性时除外）。

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
        xmlns:dt="urn:schemas-microsoft-com:datatypes"
        xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <ElementType name="CompanyName" />
  <ElementType name="Customer" sql:relation="Customers" >
    <AttributeType name="CustomerID" />

    <attribute type="CustomerID" />
    <element type="CompanyName" sql:field="CompanyName" />
  </ElementType>
</Schema>

在架构上测试示例 XPath 查询

  1. 将架构 (MySchema.xml) 保存在与已经创建的 template 虚拟名称相关联的目录中（或其中一个子目录中，在此情况下必须在 mapping-schema 特性中指定相对路径）。

  2. 创建下面的模板 (MySchemaT.xml) 并将其保存在与 template 虚拟名称相关联的目录中。此模板中的查询选择 CustomerID 为 ALFKI 的客户。
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:xpath-query mapping-schema="MySchema.xml">
    /Customer[@CustomerID="ALFKI"]
  </sql:xpath-query>
</ROOT>
  3. 下面的 URL 执行模板：
    http://IISServer/VirtualRoot/template/Schema6T.xml
  4. 下面是部分结果集：
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <Customer CustomerID="ALFKI">
    <CompanyName>Alfreds Futterkiste</CompanyName>
  </Customer>
</ROOT>

如果在 CompanyName <ElementType> 上指定 content="textOnly"，则无需在 <CompanyName> 子元素上指定 sql:field 批注。CompanyName 子元素将映射到 Customer 表中的 CompanyName 列。

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
        xmlns:dt="urn:schemas-microsoft-com:datatypes"
        xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <ElementType name="CompanyName" content="textOnly" />
  <ElementType name="Customer" sql:relation="Customers" >
    <AttributeType name="CustomerID" />

    <attribute type="CustomerID" />
    <element type="CompanyName" />
  </ElementType>
</Schema>

请参见

用于 SQL Server 的 IIS 虚拟目录管理

使用 XPath 查询

使用 HTTP 访问 SQL Server

使用 HTTP 执行模板文件


使用 <sql:relationship> 指定关系

XML 文档中的元素可以建立关系。元素可以分层嵌套，并且可以在元素之间指定 ID、IDREF 或 IDREFS 关系。

例如，在 XDR 架构中，一个 <customer> 元素包含多个 <order> 子元素。<customer> 元素映射到 Customers 表，而 <order> 元素映射到数据库中的 Orders 表。由于存在客户订单，使 Customers 和Orders 这些基础表相关。Orders 表中的 CustomerID 是一个外键，引用 Customers 表中的 CustomerID 主键。使用 <sql:relationship> 批注可在映射架构元素间建立这些关系。

在带批注的 XDR 架构中，根据元素所映射的基础表中的主键和外键关系，使用<sql:relationship> 批注分层嵌套架构元素。在指定 <sql:relationship> 批注时，必须识别：

  • 主表 (Customers) 和外表 (Orders)

  • 必要的联接条件（Orders 中的 CustomerID 是引用 Customers 表中 CustomerID 主键的外键）。

该信息用在生成适当的分层结构时（对于每一个 <customer> 元素，相关的 <order> 元素作为子元素出现）。

为了提供表名和必要的联接信息，用 <sql:relationship> 批注指定下列特性。这些特性仅与 <sql:relationship> 元素一起使用时才有效：

  • key-relation

    指定主关系（表）。

  • key

    指定 key-relation 的主键。如果主键由多列组成，则在指定时，值之间要用空格分开。在为多列键指定的值和相应的外键之间存在位置映射。

  • foreign-relation

    指定外关系（表）。

  • foreign-key

    指定 foreign-relation 中引用 key-relation 中的 key 的外键。如果外键由多个特性（列）组成，则在它们之间使用空格指定外键。在为多列键指定的值和相应的外键之间存在位置映射。

说明 必须确保 key 和 foreign-key 的Microsoft® SQL Server™ 数据类型在必要时可以隐性转换。

<sql:relationship> 标记只能添加到带批注架构中的 <element> 或 <attribute> 元素上。当在 <attribute> 上指定 <sql:relationship> 时，应存在为该特性指定的 sql:relation 和 sql:field，以确保检索单个值（相同名称的多个特性在 XML 中是无效的）。当在 <element> 上指定 <sql:relationship> 时，此关系可能产生单个值或一组值。

<sql:relationship> 标记用于指定两个实体之间的单一逻辑关系。此特性定义关系和用于定义逻辑关系的字段。在带批注架构中的 <element> 或 <attribute> 内可以指定 <sql:relationship> 的多个实例，以表示 <element> 或 <attribute> 与其所包含的元素之间的复杂关系。所有 <sql:relationship> 实例将共同定义该复杂关系。

当在 <element> 或 <attribute> 内指定 <sql:relationship> 标记的多个实例时，实例出现的顺序很重要。

必须在包含子元素和 <sql:relationship>（在元素及其子元素之间定义）的 <element> 中指定 sql:key-fields，它不提供在父元素中指定的表的主键。有关更多信息，请参见使用 sql:key-fields 标识键列。若要在结果中生成适当的嵌套，最好在所有架构中指定 sql:key-fields。

说明 在映射架构中，表名和列名等关系值是区分大小写的。

示例

若要使用这些示例创建工作示例，必须创建 nwind 虚拟目录（以访问 Northwind 数据库）和 template 类型的虚拟名称。有关创建 nwind 虚拟目录的更多信息，请参见创建 nwind 虚拟目录。

在每一示例中创建工作示例时，使用模板在映射 XDR 架构上指定 XPath 查询。在查询中使用带批注的 XDR 架构有不同的方法，如内嵌架构和 URL 中的架构。有关更多信息，请参见在查询中使用带批注的 XDR 架构。

A. 在 <element> 上指定 <sql:relationship>

此带批注的 XDR 架构包括 <Customer> 和 <Order> 元素。<Order> 元素是 <Customer> 元素的子元素。

在此架构中，在 <Order> 子元素上指定 <sql:relationship> 批注。此批注将 Orders 表中的 CustomerID 标识为引用 Customers 表的 CustomerID 主键的外键。因此，属于客户的订单将以 <Customer> 元素的子元素的形式出现。

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
        xmlns:dt="urn:schemas-microsoft-com:datatypes"
        xmlns:sql="urn:schemas-microsoft-com:xml-sql">
<ElementType name="Order" sql:relation="Orders" >
    <AttributeType name="CustomerID" />
    <AttributeType name="OrderID" />
    <AttributeType name="OrderDate" />

    <attribute type="CustomerID" />
    <attribute type="OrderID" />
    <attribute type="OrderDate" />
</ElementType>
<ElementType name="Customer" sql:relation="Customers" >
    <AttributeType name="CustomerID" />
    <attribute type="CustomerID" />
    <element type="Order" >
             <sql:relationship
                     key-relation="Customers"
                    key="CustomerID"
                    foreign-key="CustomerID"
                    foreign-relation="Orders" />
    </element>
</ElementType>
</Schema>

说明 在映射架构中，如表名和列名等关系值是区分大小写的。上例中，Customers 是 sql:relation 特性的值。相应的 key-relation 特性值也必须是 Customers。

在架构上测试示例 XPath 查询

  1. 将架构 (MySchema.xml) 保存在与已经创建的 template 虚拟名称相关联的目录中（或其中一个子目录中，在此情况下必须在 mapping-schema 特性中指定相对路径）。

  2. 创建下面的模板 (MySchemaT.xml) 并将其保存在与 template 虚拟名称相关联的目录中。此模板中的查询选择 CustomerID 为 ALFKI 的客户。
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:xpath-query mapping-schema="MySchema.xml">
    Customer[@CustomerID="ALFKI"]
  </sql:xpath-query>
</ROOT>

    为映射架构指定的目录路径相对于与 template 虚拟名称相关联的目录。还可指定绝对路径，例如：

    mapping-schema="C:\MyDir\MySchema.xml"
  3. 下面的 URL 执行模板：
    http://IISServer/VirtualRoot/template/MySchemaT.xml
  4. 下面是部分结果集：
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <Customer CustomerID="ALFKI">
    <Order CustomerID="ALFKI" OrderID="10643"
           OrderDate="1997-08-25T00:00:00" />
    <Order CustomerID="ALFKI" OrderID="10692"
           OrderDate="1997-10-03T00:00:00" />
     ...
  </Customer>
</ROOT>
B. 在 <attribute> 上指定 <sql:relationship> 并使用 ID 和 IDREFS 创建文档引用。

本例中，使用 ID 和 IDREFS 指定局部文档引用。此示例 XDR 架构由映射到 Customers 表的 <Customer> 元素组成。该元素包括映射到 Orders 表的<Order> 子元素。

本例中，指定两次 <sql:relationship>：

  • 在 <Order> 子元素上指定 <sql:relationship>。因此，属于客户的订单将以 <Customer> 元素的子元素的形式出现。

  • 再在 <Customer> 元素的 OrderIDList 特性上指定 <sql:relationship>。该特性定义为引用 <Order> 元素的 OrderID特性（ID 类型特性）的 IDREFS 类型。 因此，必需 <sql:relationship>。 在此情况下，<sql:relationship> 批注允许属于客户的一系列订单与该 <Customer> 元素一起出现。

    指定为 IDREFS 的特性可以用于引用 ID 类型特性，从而启用文档内的链接。

因为数字不是有效的 ID 值（必须是命名标记），所以已使用 sql:prefix 使 Order ID 成为字符串值。有关更多信息，请参见使用 sql:id-prefix。

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
        xmlns:dt="urn:schemas-microsoft-com:datatypes"
        xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <ElementType name="Order" sql:relation="Orders" >
    <AttributeType name="OrderID" dt:type="id" sql:id-prefix="Ord-" />
    <AttributeType name="OrderDate" />

    <attribute type="OrderID" />
    <attribute type="OrderDate" />
  </ElementType>

  <ElementType name="Customer" sql:relation="Customers">
    <AttributeType name="CustomerID"  />
     <AttributeType name="ContactName" />

    <attribute type="CustomerID" />
    <attribute type="ContactName" />
    <AttributeType name="OrderIDList" dt:type="idrefs"
                                      sql:id-prefix="Ord-"/>
    <attribute type="OrderIDList" sql:relation="Orders"
                                  sql:field="OrderID">
                 <sql:relationship
                      key-relation="Customers"
                      key="CustomerID"
                      foreign-relation="Orders"
                      foreign-key="CustomerID" />
    </attribute>
    <element type="Order">
                 <sql:relationship key-relation="Customers"
                      key="CustomerID"
                      foreign-relation="Orders"
                      foreign-key="CustomerID" />
    </element>
  </ElementType>
</Schema>

在架构上测试示例 XPath 查询

  1. 将架构 (MySchema.xml) 保存在与已经创建的 template 虚拟名称相关联的目录中（或其中一个子目录中，在此情况下必须在 mapping-schema 特性中指定相对路径）。

  2. 创建下面的模板 (MySchemaT.xml) 并将其保存在与 template 虚拟名称相关联的目录中。此模板中的查询选择 CustomerID 为 ALFKI 的客户。
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:xpath-query mapping-schema="schema/MySchema.xml">
    Customer[@CustomerID="ALFKI"]
  </sql:xpath-query>
</ROOT>

    为映射架构指定的目录路径相对于与 template 虚拟名称相关联的目录。还可指定绝对路径，例如：

    mapping-schema="C:\MyDir\MySchema.xml"
  3. 下面的 URL 执行模板：
    http://IISServer/VirtualRoot/template/MySchemaT.xml
  4. 下面是部分结果集：
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <Customer CustomerID="ALFKI" ContactName="Maria Anders"
            OrderIDList="Ord-10643 Ord-10692 Ord-10702
                         Ord-10835 Ord-10952 Ord-11011">
    <Order OrderID="Ord-10643" OrderDate="1997-08-25T00:00:00" />
    <Order OrderID="Ord-10692" OrderDate="1997-10-03T00:00:00" />
    <Order OrderID="Ord-10702" OrderDate="1997-10-13T00:00:00" />
    <Order OrderID="Ord-10835" OrderDate="1998-01-15T00:00:00" />
    <Order OrderID="Ord-10952" OrderDate="1998-03-16T00:00:00" />
    <Order OrderID="Ord-11011" OrderDate="1998-04-09T00:00:00" />
  </Customer>
</ROOT>
C. 在多个 <element> 上指定 <sql:relationship>

本例中，带批注的 XDR 架构由 <Customer>、<Order> 和 <OD> 元素组成。

<Order> 元素是 <Customer> 元素的子元素。在 <Order> 子元素上指定 <sql:relationship>，使属于客户的订单以<Customer> 的子元素的形式出现。

<Order> 元素包含 <OD> 子元素。在 <OD> 子元素上指定 <sql:relationship>，使属于订单的订单详情以 <Order> 元素的子元素的形式出现。

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
        xmlns:dt="urn:schemas-microsoft-com:datatypes"
        xmlns:sql="urn:schemas-microsoft-com:xml-sql">

<ElementType name="OD" sql:relation="[Order Details]" >
    <AttributeType name="OrderID" />
    <AttributeType name="ProductID" />

    <attribute type="OrderID" />
    <attribute type="ProductID" />
</ElementType>

<ElementType name="Order" sql:relation="Orders" >
    <AttributeType name="CustomerID" />
    <AttributeType name="OrderID" />
    <AttributeType name="OrderDate" />

    <attribute type="CustomerID" />
    <attribute type="OrderID" />
    <attribute type="OrderDate" />
    <element type="OD" >
             <sql:relationship
                   key-relation="Orders"
                   key="OrderID"
                   foreign-key="OrderID"
                   foreign-relation="[Order Details]" />
    </element>
</ElementType>

<ElementType name="Customer" sql:relation="Customers" >
    <AttributeType name="CustomerID" />

    <attribute type="CustomerID" />
    <element type="Order" >
      <sql:relationship
                key-relation="Customers"
                key="CustomerID"
                foreign-key="CustomerID"
                foreign-relation="Orders" />
    </element>
</ElementType>
</Schema>

在架构上测试示例 XPath 查询

  1. 将架构 (MySchema.xml) 保存在与已经创建的 template 虚拟名称相关联的目录中（或其中一个子目录中，在此情况下必须在 mapping-schema 特性中指定相对路径）。

  2. 创建下面的模板 (MySchemaT.xml) 并将其保存在与 template 虚拟名称相关联的目录中。模板中的查询返回 CustomerID 为 ALFKI、OrderID 为 10643 的客户的订单信息。
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:xpath-query mapping-schema="MySchema.xml">
    /Customer[@CustomerID="ALFKI"]/Order[@OrderID=10643]
  </sql:xpath-query>
</ROOT>

    为映射架构指定的目录路径相对于与 template 虚拟名称相关联的目录。还可指定绝对路径，例如：

    mapping-schema="C:\MyDir\MySchema.xml"
  3. 下面的 URL 执行模板：
    http://IISServer/VirtualRoot/template/MySchemaT.xml
  4. 下面是部分结果集：
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
<Order CustomerID="ALFKI" OrderID="10643"
                          OrderDate="1997-08-25T00:00:00">
  <OD OrderID="10643" ProductID="28" />
  <OD OrderID="10643" ProductID="39" />
  <OD OrderID="10643" ProductID="46" />
</Order>
</ROOT>
D. 指定间接关系

本例中，带批注的 XDR 架构由 <Customer>、<OD> 元素组成。这些元素之间的关系是间接的（Customers 表通过 Orders 表与 Order Details 表相关）。为了使客户与订单详情相关，首先必须指定 Customer 表和 Orders 表之间的关系。然后，指定 Orders 表和 Order Details 表之间的关系。

架构如下所示：

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
        xmlns:dt="urn:schemas-microsoft-com:datatypes"
        xmlns:sql="urn:schemas-microsoft-com:xml-sql">
<ElementType name="OD" sql:relation="[Order Details]" >
    <AttributeType name="OrderID" />
    <AttributeType name="ProductID" />
    <AttributeType name="UnitPrice" />

    <attribute type="OrderID" />
    <attribute type="ProductID" />
    <attribute type="UnitPrice" />
</ElementType>
<ElementType name="Customer" sql:relation="Customers" >
    <AttributeType name="CustomerID" />
    <attribute type="CustomerID" />
    <element type="OD" >
             <sql:relationship
                    key-relation="Customers"
                    key="CustomerID"
                    foreign-relation="Orders"
                    foreign-key="CustomerID"/>
             <sql:relationship
                    key-relation="Orders"
                    key="OrderID"
                    foreign-relation="[Order Details]"
                    foreign-key="OrderID" />
    </element>
</ElementType>
</Schema>

在架构上测试示例 XPath 查询

  1. 将架构 (MySchema.xml) 保存在与已经创建的 template 虚拟名称相关联的目录中（或其中一个子目录中，在此情况下必须在 mapping-schema 特性中指定相对路径）。

  2. 创建下面的模板 (MySchemaT.xml) 并将其保存在与 template 虚拟名称相关联的目录中。模板中的查询返回 CustomerID 为 ALFKI、OrderID 为 10643 的客户的订单信息。
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql" >
<sql:xpath-query mapping-schema="TestSchema1.xml" >
/Customer[@CustomerID="ALFKI"]
</sql:xpath-query>
</ROOT>

    为映射架构指定的目录路径相对于与 template 虚拟名称相关联的目录。还可指定绝对路径，例如：

    mapping-schema="C:\MyDir\MySchema.xml"
  3. 下面的 URL 执行模板：
    http://IISServer/VirtualRoot/template/MySchemaT.xml
  4. 下面是部分结果：
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <Customer CustomerID="ALFKI">
    <OD OrderID="10643" ProductID="28" UnitPrice="45.6" />
    <OD OrderID="10643" ProductID="39" UnitPrice="18" />
    <OD OrderID="10643" ProductID="46" UnitPrice="12" />
    ...
  </Customer>
</ROOT>
E. 指定多键联接关系

在使用 <sql:relationship> 指定联接的过程中，可指定涉及两个或两个以上列的联接。在此情况下，使用一个空格列出 key 和 foreign-key 的列名。

本例假设存在以下两个表：

  • Cust(fname, lname)

  • Ord(OrderID, fname, lname)

fname 和 lname 列构成 Cust 表的主键。OrderID 为 Ord 表的主键。Ord 表中的fname 和 lname 为外键，引用Cust 表的 fname 和 lname 主键。

此架构由 <Cust> 和 <Ord> 元素组成。<sql:relationship>用于联接这些元素。

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
        xmlns:dt="urn:schemas-microsoft-com:datatypes"
        xmlns:sql="urn:schemas-microsoft-com:xml-sql">
<ElementType name="Ord" sql:relation="Ord" >
    <AttributeType name="OrderID" />

    <attribute type="OrderID" />
</ElementType>

<ElementType name="Cust" sql:relation="Cust" >
    <AttributeType name="fname" />
    <AttributeType name="lname" />
    <attribute type="fname" />
    <attribute type="lname" />
    <element type="Ord" >
             <sql:relationship
                    key-relation="Cust"
                    key="fname lname"
                    foreign-relation="Ord"
                    foreign-key="fname lname"/>
    </element>
</ElementType>
</Schema>

在架构上测试示例 XPath 查询

  1. 创建两个表：Cust 和 Ord。

  2. 添加以下示例数据：
    INSERT INTO Cust values ('Nancy', 'Davolio')
INSERT INTO Cust values('Andrew', 'Fuller')
INSERT INTO Ord values (1,'Nancy', 'Davolio')
INSERT INTO Ord values (2,'Nancy', 'Davolio')
INSERT INTO Ord values (3,'Andrew', 'Fuller')
  3. 将架构 (MySchema.xml) 保存在与已经创建的 template 虚拟名称相关联的目录中（或其中一个子目录中，在此情况下必须在 mapping-schema 特性中指定相对路径）。

  4. 创建下面的模板 (MySchemaT.xml) 并将其保存在与 template 虚拟名称相关联的目录中。模板中的查询返回客户信息。
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql" >
  <sql:xpath-query mapping-schema="TestSchema1.xml" >
    /Cust
  </sql:xpath-query>
</ROOT>

    为映射架构指定的目录路径相对于与 template 虚拟名称相关联的目录。还可指定绝对路径，例如：

    mapping-schema="C:\MyDir\MySchema.xml"
  5. 下面的 URL 执行模板：
    http://IISServer/VirtualRoot/template/MySchemaT.xml
  6. 下面是部分结果：
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <Cust fname="Andrew" lname="Fuller">
    <Ord OrderID="3" />
  </Cust>
  <Cust fname="Nancy" lname="Davolio">
    <Ord OrderID="1" />
    <Ord OrderID="2" />
  </Cust>
</ROOT>

请参见

用于 SQL Server 的 IIS 虚拟目录管理

使用 XPath 查询

使用 HTTP 访问 SQL Server

使用 HTTP 执行模板文件


使用 sql:is-constant 创建常量元素

由于默认映射的缘故，XDR 架构中的每个元素和特性都映射到数据库中的表和列。有时，也许要在 XDR 架构中创建一个元素，该元素不映射到任何数据库的表或列，但仍出现在 XML 文件中。这些元素称为常量元素。若要创建常量元素，请指定 sql:is-constant 批注。sql:is-constant 取布尔值 (0 = FALSE, 1 = TRUE)。

在 <ElementType> 上指定该批注，它不映射到任何数据库表，因此成为常量元素。sql:is-constant 批注可用于：

  • 将顶层元素添加到 XML 文档中。XML 文档需要一个顶层元素（<root> 元素）。

  • 创建容器元素，例如包裹所有 Orders 的 <Orders> 元素。
示例

若要使用这些示例创建工作示例，必须创建 nwind 虚拟目录（以访问 Northwind 数据库）和 template 类型的虚拟名称。有关创建 nwind 虚拟目录的更多信息，请参见创建 nwind 虚拟目录。

在每一示例中创建工作示例时，使用模板在映射 XDR 架构上指定 XPath 查询。在查询中使用带批注的 XDR 架构有不同的方法，如内嵌架构和 URL 中的架构。有关更多信息，请参见在查询中使用带批注的 XDR 架构。

A. 指定添加容器元素的 sql:is-constant

在此带批注的 XDR 架构中，<OrderList> 定义为包含所有 <Orders> 子元素的常量元素。在 OrderList <ElementType>上指定 sql:is-constant 批注，使之成为常量，因此不映射到任何数据库表。尽管 <OrderList> 元素不映射到任何数据库表/列，但仍作为包含 <Orders> 子元素的容器元素出现在所得到的 XML 中。

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
xmlns:dt="urn:schemas-microsoft-com:datatypes"
xmlns:sql="urn:schemas-microsoft-com:xml-sql">
<ElementType name="Orders" >
   <AttributeType name="OrderID" />
   <attribute type="OrderID" />
</ElementType>
<ElementType name="OrderList" sql:is-constant="1">
   <element type="Orders">
      <sql:relationship
                   key-relation="Customers"
                   foreign-relation="Orders"
                   key="CustomerID"
                   foreign-key="CustomerID" />
   </element>
</ElementType>
<ElementType name="Customers" >
   <AttributeType name="CustomerID" />
   <attribute type="CustomerID" />
   <element type="OrderList" />
</ElementType>
</Schema>

在架构上测试示例 XPath 查询

  1. 将架构 (MySchema.xml) 保存在与已经创建的 template 虚拟名称相关联的目录中（或其中一个子目录中，在此情况下必须在 mapping-schema 特性中指定相对路径）。

  2. 创建下面的模板 (MySchemaT.xml) 并将其保存在与 template 虚拟名称相关联的目录中。模板中的 XPath 查询选择所有 EmployeeID 特性值为 1 的 <Employees> 元素。
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql" >
<sql:xpath-query mapping-schema="TestSchema1.xml" >
/Customers
</sql:xpath-query>
</ROOT>

    为映射架构指定的目录路径相对于与 template 虚拟名称相关联的目录。还可指定绝对路径，例如：

    mapping-schema="C:\MyDir\MySchema.xml"
  3. 下面的 URL 执行模板：
    http://IISServer/VirtualRoot/template/MySchemaT.xml
  4. 下面是部分结果集：
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <Customers CustomerID="ALFKI">
    <OrderList>
      <Orders OrderID="10643" />
      <Orders OrderID="10692" />
      <Orders OrderID="10702" />
      <Orders OrderID="10835" />
      <Orders OrderID="10952" />
      <Orders OrderID="11011" />
    </OrderList>
</Customers>
...
</ROOT>

请参见

用于 SQL Server 的 IIS 虚拟目录管理

使用 XPath 查询

使用 HTTP 访问 SQL Server

使用 HTTP 执行模板文件


使用 sql:map-field 从所得到的 XML 文档中排除架构元素

由于默认映射的缘故，XDR 架构中的每个元素和特性都映射到数据库中的表和列。有时，也许要在 XDR 架构中创建一个元素，该元素不映射到任何数据库表或列，并且也不出现在 XML 中。为此可指定 sql:map-field 批注。

sql:map-field 批注与 sql:is-constant 的不同之处在于，未映射的元素和特性不出现在 XML 文档中。如果无法修改架构或者架构被用于验证来自其它数据源、但包含您的数据库中所没有的数据的 XML 时，sql:map-field 特别有用。

sql:map-field 取布尔值 (0 = FALSE, 1 = TRUE)。sql:map-field 批注仅在包含纯文本内容 (content=textOnly)的 <attribute>、<element> 或 <ElementTypes> 上有效。该批注在映射到表的 <element> 或 <ElementTypes> 上无效。

示例

若要使用这些示例创建工作示例，必须创建 nwind 虚拟目录（以访问 Northwind 数据库）和 template 类型的虚拟名称。有关创建 nwind 虚拟目录的更多信息，请参见创建 nwind 虚拟目录。

在每一示例中创建工作示例时，使用模板在映射 XDR 架构上指定 XPath 查询。在查询中使用带批注的 XDR 架构有不同的方法，如内嵌架构和 URL 中的架构。有关更多信息，请参见在查询中使用带批注的 XDR 架构。

A. 指定 sql:map-field 批注

假设有一个来自某个其它数据源的 XDR 架构。此 XDR 架构由具有 EmployeeID、FirstName、LastName 和 HomeAddress 特性的 <Employees> 元素组成。

在将该 XDR 架构映射到数据库的 Employees 表的过程中，在 HomeAddress 特性上指定 sql:map-field，因为 Employees 表没有存储职员的家庭地址。 结果，当在映射架构上指定 XPath 查询时，该特性不在所得到的 XML 文档中返回。

架构的其余部分则发生默认映射。<Employees> 元素映射到 Employees 表，而所有特性映射到 Employees 表中的同名列。有关默认映射的更多信息，请参见 XDR 元素和特性到表和列的默认映射。

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
        xmlns:dt="urn:schemas-microsoft-com:datatypes"
        xmlns:sql="urn:schemas-microsoft-com:xml-sql">

<ElementType name="Employees" >
    <AttributeType name="EmployeeID" />
    <AttributeType name="FirstName" />
    <AttributeType name="LastName" />
    <AttributeType name="HomeAddress" />

    <attribute type="EmployeeID" />
    <attribute type="FirstName" />
    <attribute type="LastName" />
    <attribute type="HomeAddress" sql:map-field="0" />
</ElementType>
</Schema>

在架构上测试示例 XPath 查询

  1. 将架构 (MySchema.xml) 保存在与已经创建的 template 虚拟名称相关联的目录中（或其中一个子目录中，在此情况下必须在 mapping-schema 特性中指定相对路径）。

  2. 创建下面的模板 (Schema9T.xml) 并将其保存在与 template 虚拟名称相关联的目录中。此模板中的查询选择 EmployeeID 等于 1 的所有职员。
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
<sql:xpath-query mapping-schema="MySchema.xml">
  /Employees[@EmployeeID=1]
</sql:xpath-query>
</ROOT>

    为映射架构指定的目录路径相对于与 template 虚拟名称相关联的目录。还可指定绝对路径，例如：

    mapping-schema="C:\MyDir\MySchema.xml"
  3. 下面的 URL 执行模板：
    http://IISServer/VirtualRoot/template/MySchemaT.xml
  4. 下面是部分结果集：
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
    <Employees EmployeeID="1" FirstName="Nancy" LastName = "Davolio"/>
</ROOT>

    注意，EmployeeID、FirstName 和 LastName 存在，但 HomeAddress 不存在，因为映射架构指定 sql:map-field 特性为 0。

请参见

用于 SQL Server 的 IIS 虚拟目录管理

使用 XPath 查询

使用 HTTP 访问 SQL Server

使用 HTTP 执行模板文件


使用 sql:limit-field 和 sql:limit-value 筛选值

可基于一些限制值限制从数据库查询返回的行。这些批注用于标识含限制值的数据库列，并指定用于筛选返回数据的特定限制值。

sql:limit-field 批注用于标识包含限制值的列。sql:limit-field 用于限制使用 <sql:relationship> 指定的联接关系。sql:limit-field 必须用在指定了 <sql:relationship> 的元素或特性上。

sql:limit-value 批注用于指定 sql:limit-field 批注中指定的列的限制值。此批注为可选项。如果未指定 sql:limit-value，则假定为空值。

示例

若要使用这些示例创建工作示例，必须创建 nwind 虚拟目录（以访问 Northwind 数据库）和 template 类型的虚拟名称。有关创建 nwind 虚拟目录的更多信息，请参见创建 nwind 虚拟目录。

在每一示例中创建工作示例时，使用模板在映射 XDR 架构上指定 XPath 查询。在查询中使用带批注的 XDR 架构有不同的方法，如内嵌架构和 URL 中的架构。有关更多信息，请参见在查询中使用带批注的 XDR 架构。

A. 将返回的客户地址限制为特定的地址类型

本例中，数据库包含两个表：

  • Customer (CustomerID, CompanyName)

  • Addresses (CustomerID, AddressType, StreetAddress)

客户会有一个发货和/或一个计帐地址（AddressType 列值为 Shipping 和 Billing)。

在下面这个映射架构中，ShipTo 架构特性映射到 Addresses 关系的 StreetAddress 列。通过指定 sql:limit-field 和 sql:limit-value 批注，将为该特性返回的值仅限于 Shipping 地址。同样，BillTo 架构特性仅返回客户的 Billing 地址。

架构如下所示：

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
        xmlns:dt="urn:schemas-microsoft-com:datatypes"
        xmlns:sql="urn:schemas-microsoft-com:xml-sql">

<ElementType name="Customer" sql:relation="Customer" >
    <AttributeType name="CustomerID" />
    <AttributeType name="CompanyName" />
    <AttributeType name="BillTo" />
    <AttributeType name="ShipTo" />

    <attribute type="CustomerID" />
    <attribute type="CompanyName" />
    <attribute type="BillTo"
                sql:limit-field="AddressType"
                sql:limit-value="billing"
                sql:field="StreetAddress"
                sql:relation="Addresses" >
                <sql:relationship
                        key="CustomerID"
                        key-relation="Customer"
                       foreign-relation="Addresses"
                       foreign-key="CustomerID" />
    </attribute>
    <attribute type="ShipTo"
                sql:limit-field="AddressType"
                sql:limit-value="shipping"
                sql:field="StreetAddress"
                sql:relation="Addresses" >
                <sql:relationship
                     key="CustomerID"
                     key-relation="Customer"
                     foreign-relation="Addresses"
                     foreign-key="CustomerID" />
    </attribute>
</ElementType>
</Schema>

在架构上测试示例 XPath 查询

  1. 创建两个表：
    CREATE TABLE Customer (CustomerID int primary key,
                       CompanyName varchar(30))
CREATE TABLE Addresses(CustomerID int,
                       StreetAddress varchar(50),
                       AddressType varchar(10))
  2. 添加示例数据：
    INSERT INTO Customer values (1, 'Company A')
INSERT INTO Customer values (2, 'Company B')

INSERT INTO Addresses values
            (1, 'Obere Str. 57 Berlin', 'billing')
INSERT INTO Addresses values
            (1, 'Avda. de la Constitución 2222México D.F.', 'shipping')
INSERT INTO Addresses values
            (2, '120 Hanover Sq., London', 'billing')
INSERT INTO Addresses values
            (2, 'Forsterstr. 57, Mannheim', 'shipping')
  3. 将架构 (MySchema.xml) 保存在与已经创建的 template 虚拟名称相关联的目录中（或其中一个子目录中，在此情况下必须在 mapping-schema 特性中指定相对路径）。

  4. 创建下面的模板 (MySchemaT.xml) 并将其保存在与 template 虚拟名称相关联的目录中。此模板中的查询选择 CustomerID 为 ALFKI 的客户。
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:xpath-query mapping-schema="MySchemaT.xml">
    /Customer
  </sql:xpath-query>
</ROOT>

    为映射架构指定的目录路径相对于与 template 虚拟名称相关联的目录。还可指定绝对路径，例如：

    mapping-schema="C:\MyDir\MySchema.xml"
  5. 执行下面的 URL：
    http://IISServer/VirtualRoot/TemplateVirtualName/MySchemaT.xml

结果如下：

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <Customer CustomerID="1" CompanyName="Company A"
          BillTo="Obere Str. 57 Berlin"
          ShipTo="Avda. de la Constitución 2222México D.F." />
  <Customer CustomerID="2" CompanyName="Company B"
          BillTo="120 Hanover Sq., London"
          ShipTo="Forsterstr. 57, Mannheim" />
</ROOT>

请参见

用于 SQL Server 的 IIS 虚拟目录管理

使用 XPath 查询

使用 HTTP 访问 SQL Server

使用 HTTP 执行模板文件


使用 sql:key-fields 标识键列

当在 XDR 架构上指定 XPath 查询时，多数情况下，需要键信息以便在结果中获得适当的嵌套。指定 sql:key-fields 批注是确保生成适当层次结构的一种方法。

说明 若要在结果中生成适当的嵌套，建议在所有的架构中指定 sql:key-fields。

在许多情况下，需要了解如何唯一地标识表中的行以生成适当的 XML 层次结构。可将 sql:key-fields 批注添加到 <element> 和 <ElementType> 中以标识那些唯一标识表中行的列。

sql:key-fields 的值标识列，这些列唯一地标识 <ElementType> 中指定的关系中的行。如果需要不止一个列来唯一地标识某行，则列值将用空格分开。

必须在包含子元素和 <sql:relationship>（在元素及其子元素之间定义）的元素中指定 sql:key-fields，它不提供在父元素中指定的表的主键。

示例

若要使用这些示例创建工作示例，必须创建 nwind 虚拟目录（以访问 Northwind 数据库）和 template 类型的虚拟名称。有关创建 nwind 虚拟目录的更多信息，请参见创建 nwind 虚拟目录。

在每一示例中创建工作示例时，使用模板在映射 XDR 架构上指定 XPath 查询。在查询中使用带批注的 XDR 架构有不同的方法，如内嵌架构和 URL 中的架构。有关更多信息，请参见在查询中使用带批注的 XDR 架构。

A. <sql:relationship> 未提供足够信息时生成适当的嵌套

下例显示必须在哪里指定 sql:key-fields。

请考虑下列架构。此架构指定 <Order> 和 <Customer> 元素间的层次结构，在该层次结构中，<Order> 元素为父元素，<Customer> 元素为子元素。

<sql:relationship> 标记用于指定父子关系。<sql:relationship> 将 CustomerID 标识为 Orders 表中引用 Customers 表中的 CustomerID key 的 foreign-key。<sql:relationship> 提供的这些信息不足以唯一标识父表 (Orders) 中的行。因此，没有 sql:key-fields 就无法生成准确的层次结构。

如果在 <Order> 上指定 sql:key-fields，则批注唯一标识父表（Orders 表）中的行，其子元素出现在父元素下面。

架构显示如下：

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
        xmlns:dt="urn:schemas-microsoft-com:datatypes"
        xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <ElementType name="Customer" sql:relation="Customers">
    <AttributeType name="CustomerID" />
    <AttributeType name="ContactName" />

    <attribute type="CustomerID" />
    <attribute type="ContactName" />
  </ElementType>

  <ElementType name="Order" sql:relation="Orders"
                            sql:key-fields="OrderID" >
    <AttributeType name="OrderID" />
    <AttributeType name="CustomerID" />

    <attribute type="OrderID" />
    <attribute type="CustomerID" />
    <element type="Customer" >
             <sql:relationship
                         key-relation="Orders"
                         key="CustomerID"
                         foreign-relation="Customers"
                         foreign-key="CustomerID" />
    </element>
     </ElementType>
</Schema>

创建该架构的工作示例

  1. 将架构 (MySchema.xml) 保存在与已经创建的 template 虚拟名称相关联的目录中（或其中一个子目录中，在此情况下必须在 mapping-schema 特性中指定相对路径）。

  2. 创建下面的模板 (MySchemaT.xml) 并将其保存在与 template 虚拟名称相关联的目录中。此模板中的 XPath 查询返回所有的 <Order> 元素。
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:xpath-query mapping-schema="MySchema.xml">
    /Order
  </sql:xpath-query>
</ROOT>

    为映射架构指定的目录路径相对于与 template 虚拟名称相关联的目录。还可指定绝对路径，例如：

    mapping-schema="C:\MyDir\MySchema.xml"
  3. 下面的 URL 执行模板：
    http://IISServer/VirtualRoot/template/MySchemaT.xml

下面是部分结果集：

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <Order OrderID="10248" CustomerID="VINET">
    <Customer CustomerID="VINET" ContactName="Paul Henriot" />
  </Order>
  <Order OrderID="10249" CustomerID="TOMSP">
    <Customer CustomerID="TOMSP" ContactName="Karin Josephs" />
  </Order>
</ROOT>
B. 指定 sql:key-fields 以在结果中生成适当的嵌套

在此架构中，不存在使用 <sql:relationship> 指定的层次结构。此架构仍需要指定 sql:key-fields 批注以唯一标识 Employees 表中的职员。

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
   xmlns:dt="urn:schemas-microsoft-com:datatypes"
   xmlns:sql="urn:schemas-microsoft-com:xml-sql">
   <ElementType name="Region" content="textOnly"  >
      <AttributeType name="EmployeeID" />
      <attribute type="EmployeeID" />
   </ElementType>

   <ElementType name="Employees" sql:key-fields="EmployeeID" >
      <element type="Region" />
   </ElementType>
</Schema>

创建该架构的工作示例

  1. 将架构 (MySchema.xml) 保存在与已经创建的 template 虚拟名称相关联的目录中（或其中一个子目录中，在此情况下必须在 mapping-schema 特性中指定相对路径）。

  2. 创建下面的模板 (MySchemaT.xml) 并将其保存在与 template 虚拟名称相关联的目录中。此模板中的 XPath 查询返回所有的 <Order> 元素。
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:xpath-query mapping-schema="MySchema.xml">
    /Employees
  </sql:xpath-query>
</ROOT>

    为映射架构指定的目录路径相对于与 template 虚拟名称相关联的目录。还可指定绝对路径，例如：

    mapping-schema="C:\MyDir\MySchema.xml"
  3. 下面的 URL 执行模板：
    http://IISServer/VirtualRoot/template/MySchemaT.xml
This is the result:
<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
    <Employees>
        <Region EmployeeID="1">WA</Region>
    </Employees>
    <Employees>
        <Region EmployeeID="2">WA</Region>
    </Employees>
</ROOT>

请参见

用于 SQL Server 的 IIS 虚拟目录管理

使用 XPath 查询

使用 HTTP 访问 SQL Server

使用 HTTP 执行模板文件


使用 sql:target-namespace 指定目标命名空间

sql:target-namespace 批注可用于将默认命名空间的元素和特性放到其它命名空间中。sql:target-namespace 特性只能添加到 XDR 架构中的 <Schema> 标记。

sql:target-namespace 的值是命名空间 URI（统一资源标识符），用于生成映射架构中指定的元素和特性。该 URI 适用于默认命名空间中的所有元素和特性。对该架构的查询所返回的 XML 文档包含 xmlns:prefix="uri" 声明，并相应地给元素名和特性名加上前缀。使用的 URI 来自 sql:target-namespace 批注的值。而前缀是任意生成的，并且不对应于架构中的任何值（即使在架构中使用这些前缀）。

示例

若要使用这些示例创建工作示例，必须创建 nwind 虚拟目录（以访问 Northwind 数据库）和 template 类型的虚拟名称。有关创建 nwind 虚拟目录的更多信息，请参见创建 nwind 虚拟目录。

在每一示例中创建工作示例时，使用模板在映射 XDR 架构上指定 XPath 查询。在查询中使用带批注的 XDR 架构有不同的方法，如内嵌架构和 URL 中的架构。有关更多信息，请参见在查询中使用带批注的 XDR 架构。

A. 指定目标命名空间

在下例中，使用 sql:target-namespace 批注指定目标命名空间。结果是：所有本应放入默认命名空间的元素和特性都被重定向到目标命名空间 (MyNamespace)。

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
        xmlns:dt="urn:schemas-microsoft-com:datatypes"
        xmlns:sql="urn:schemas-microsoft-com:xml-sql"
        sql:target-namespace="urn:MyNamespace">
<ElementType name="Orders" >
   <AttributeType name="OrderID" />
   <attribute type="OrderID"/>
</ElementType>
<ElementType name="Customers" >
   <AttributeType name="CustomerID" />
   <attribute type="CustomerID" />
   <AttributeType name="Contact" />
   <attribute type="Contact" sql:field="ContactName" />
   <element type="Orders" >
      <sql:relationship
            key="CustomerID"
            foreign-key="CustomerID"
            key-relation="Customers"
            foreign-relation="Orders" />
   </element>
</ElementType>
</Schema>

在架构上测试示例 XPath 查询

  1. 将架构 (MySchema.xml) 保存在与已经创建的 template 虚拟名称相关联的目录中（或其中一个子目录中，在此情况下必须在 mapping-schema 特性中指定相对路径）。

  2. 创建下面的模板 (MySchemaT.xml) 并将其保存在与 template 虚拟名称相关联的目录中：
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:xpath-query mapping-schema="MySchema.xml"
                   xmlns:x="urn:MyNamespace" >
    x:Customers
  </sql:xpath-query>
</ROOT>

    此模板中的 XPath 查询请求命名空间"MyNamespace"中定义的所有 <Customer> 元素。在此模板中，前缀 x 绑定到命名空间。

    为映射架构指定的目录路径相对于与 template 虚拟名称相关联的目录。还可指定绝对路径，例如：

    mapping-schema="C:\MyDir\MySchema.xml"
  3. 下面的 URL 执行模板：
    http://IISServer/VirtualRoot/template/TargetNST.xml
  4. 下面是结果：
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <y0:Customers xmlns:y0="urn:MyNamespace" CustomerID="ALFKI"
                                           Contact="Maria Anders">
    <y0:Orders OrderID="10643" />
    <y0:Orders OrderID="10692" />
    <y0:Orders OrderID="10702" />
    <y0:Orders OrderID="10835" />
    <y0:Orders OrderID="10952" />
    <y0:Orders OrderID="11011" />
  </y0:Customers>
</ROOT>

注意，生成的前缀是任意的，但映射到同一命名空间。

请参见

用于 SQL Server 的 IIS 虚拟目录管理

使用 XPath 查询

使用 HTTP 访问 SQL Server

使用 HTTP 执行模板文件


使用 sql:id-prefix 创建有效的 ID、IDREF 和 IDREFS 类型特性

可以将特性指定为 ID 类型特性。这样，被指定为 IDREF 或 IDREFS 类型的特性即可用于引用 ID 类型特性，从而启用文档内的链接。

ID、IDREF 和 IDREFS 对应于数据库中的 PK/FK（主键/外键）关系，它们之间几乎没什么不同。在 XML 文档中，ID 类型特性的值必须唯一。如果 XML 文档中有 CustomerID 和 OrderID 特性，则这些值必须不同。然而，在数据库中，CustomerID 和 OrderID 列可以有相同的值（例如，CustomerID = 1 和 OrderID = 1 在数据库中有效）。

为了使 ID、IDREF 和 IDREFS 特性有效：

  • 在 XML 文档内，ID 的值必须唯一。

  • 对于每一个 IDREF 和 IDREFS，XML 文档中都必须有被引用的 ID 值。

  • ID、IDREF 和 IDREFS 值必须是命名标记（例如，整型值 101 不能是 ID 值）。

  • ID、IDREF 和 IDREFS 类型特性不能映射到数据类型为 text、ntext、image 或任何其它二进制（如 timestamp）的列。

如果 XML 文档包含多个 ID，若要确保值的唯一性，应使用 sql:id-prefix 批注。有关 sql:id-prefix 的更多信息，请参见使用 sql:id-prefix。

请参见

用于 SQL Server 的 IIS 虚拟目录管理

使用 XPath 查询

使用 HTTP 访问 SQL Server

使用 HTTP 执行模板文件


使用 sql:id-prefix

sql:id-prefix 批注用于创建有效的 XML ID、IDREF 或 IDREFS。

在 XML 文档中，ID 类型特性的值必须唯一。如果 XML 文档中存在多个 ID 类型特性，为确保这些特性值唯一，应为 ID 类型特性指定 sql:id-prefix 特性。sql:id-prefix 还用于从数字创建命名标记。为 sql:id-prefix 指定的值必须是有效的名称字符。

sql:id-prefix 特性用于在字符串中预先准备 ID、IDREF 和 IDREFS 的值，从而使其唯一。不为确保 ID、IDREF 或 IDREFS 值的唯一性和前缀的有效性而进行检查。

在不是 ID、IDREF 或 IDREFS 类型的特性上忽略 sql:id-prefix。

说明 ID、IDREF 和 IDREFS 特性的每个值都限制在 4,000 个字符内，包括前缀（若指定）。

示例

若要使用这些示例创建工作示例，必须创建 nwind 虚拟目录（以访问 Northwind 数据库）和 template 类型的虚拟名称。有关创建 nwind 虚拟目录的更多信息，请参见创建 nwind 虚拟目录。

在每一示例中创建工作示例时，使用模板在映射 XDR 架构上指定 XPath 查询。在查询中使用带批注的 XDR 架构有不同的方法，如内嵌架构和 URL 中的架构。有关更多信息，请参见在查询中使用带批注的 XDR 架构。

A. 为 ID 类型特性指定 sql:id-prefix

在此 XDR 架构中，OrderID 和 EmployeeID 特性被声明为 ID 类型。为确保 ID 唯一且有效，为这些特性指定了 sql:id-prefix 批注：

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
        xmlns:dt="urn:schemas-microsoft-com:datatypes"
        xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <ElementType name="Order" sql:relation="Orders" sql:key-fields="OrderID">
    <AttributeType name="OrderID" dt:type="id" sql:id-prefix="Ord-" />
    <AttributeType name="OrderDate" />

    <attribute type="OrderID" />
    <attribute type="OrderDate" />
  </ElementType>

  <ElementType name="Employee" sql:relation="Employees">
    <AttributeType name="EmployeeID" dt:type="id" />
     <AttributeType name="LastName" />

    <attribute type="EmployeeID" />
    <attribute type="LastName" />
    <AttributeType name="OrderList" dt:type="idrefs"
                                 sql:id-prefix="Ord-" />
    <attribute type="OrderList" sql:relation="Orders" sql:field="OrderID">
        <sql:relationship
                key-relation="Employees"
                key="EmployeeID"
                foreign-relation="Orders"
                foreign-key="EmployeeID" />
    </attribute>
    <element type="Order">
        <sql:relationship key-relation="Employees"
                          key="EmployeeID"
                          foreign-relation="Orders"
                          foreign-key="EmployeeID" />
    </element>
  </ElementType>
</Schema>

在架构上测试示例 XPath 查询

  1. 将架构 (MySchema.xml) 保存在与已经创建的 template 虚拟名称相关联的目录中（或其中一个子目录中，在此情况下必须在 mapping-schema 特性中指定相对路径）。

  2. 创建下面的模板 (MySchemaT.xml) 并将其保存在与 template 虚拟名称相关联的目录中。此模板中的 XPath 查询返回 EmployeeID 为 1 的 <Employee> 和 <Order> 子元素。
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:xpath-query mapping-schema="MySchema.xml">
    Employee[@EmployeeID="1"]
  </sql:xpath-query>
</ROOT>
  3. 下面的 URL 执行模板：
    http://IISServer/VirtualRoot/template/MySchemaT.xml

下面是部分结果集：

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <Employee EmployeeID="1" LastName="Davolio" OrderList="Ord-10258 Ord-
            10270 Ord-10275 Ord-10285">
    <Order OrderID="Ord-10258" OrderDate="1996-07-17T00:00:00" />
    <Order OrderID="Ord-10270" OrderDate="1996-08-01T00:00:00" />
    <Order OrderID="Ord-10275" OrderDate="1996-08-07T00:00:00" />
    <Order OrderID="Ord-10285" OrderDate="1996-08-20T00:00:00" />
  </Employee>
</ROOT>

请参见

用于 SQL Server 的 IIS 虚拟目录管理

使用 XPath 查询

使用 HTTP 访问 SQL Server

使用 HTTP 执行模板文件


数据类型强制

可在 XDR 架构中指定元素或特性的数据类型。当使用 XDR 架构从数据库中析取数据时，将输出适当的数据格式作为查询结果。dt:type 和 sql:datatype 批注用于控制 XDR 数据类型和 Microsoft® SQL Server™ 2000 数据类型之间的映射。

dt:type

可使用 dt:type 特性指定映射到列的特性或元素的 XML 数据类型。可在 <AttributeType> 或 <ElementType> 上指定 dt:type 特性。dt:type 影响从服务器返回的文档并且还影响执行 Xpath 查询。当对包含 dt:type 的映射架构执行 Xpath 查询时，Xpath 使用在处理查询时所指定的数据类型。有关 XPath 如何使用 dt:type 的更多信息，请参见 XPath 数据类型。

在返回的文档中，所有 SQL Server 数据类型都转换成字符串表示法。有些数据类型要求其它转换。下表列出用于各种 dt:type 值的转换。

XML 数据类型 | SQL Server 转换
bit | CONVERT(bit, COLUMN)
date | LEFT(CONVERT(nvarchar(4000), COLUMN, 126), 10)
fixed.14.4 | CONVERT(money, COLUMN)
id/idref/idrefs | id-prefix + CONVERT(nvarchar(4000), COLUMN, 126)
nmtoken/nmtokens | id-prefix + CONVERT(nvarchar(4000), COLUMN, 126)
time/time.tz | SUBSTRING(CONVERT(nvarchar(4000), COLUMN, 126), 1+CHARINDEX(N'T', CONVERT(nvarchar(4000), COLUMN, 126)), 24)
所有其它类型 | 无其它转换

注意某些 SQL Server 值不能转换为特定的 XML 数据类型，因为不可能进行转换（例如将"XYZ"转换为 number 数据类型）或是因为此值超出了该数据类型的范围（例如将 -100000 转换为 ui2）。不兼容的类型转换可能导致无效的 XML 文档或 SQL Server 错误。

从 SQL Server 数据类型映射到 XML 数据类型

此表显示从 SQL Server 数据类型到 XML 数据类型的自然映射。

SQL Server 数据类型 | XML 数据类型
bigint | i8
binary | bin.base64
bit | boolean
char | char
datetime | datetime
decimal | r8
float | r8
image | bin.base64
int | int
money | r8
nchar | String
ntext | String
nvarchar | String
numeric | r8
real | r4
smalldatetime | datetime
smallint | i2
smallmoney | fixed.14.4
sysname | String
text | String
timestamp | ui8
tinyint | ui1
varbinary | bin.base64
varchar | String
uniqueidentifier | uuid

sql:datatype

XML 数据类型 bin.base64 映射到各种 Microsoft® SQL Server™ 数据类型（binary、image、varbinary）。为了将 XML 数据类型 bin.base64 显式映射到特定的 SQL Server 数据，应使用 sql:datatype 批注。sql:datatype 指定特性映射到的列的 SQL Server 数据类型。

这在数据库中存储数据时很有用。通过指定 sql:datatype 批注，可标识显式 SQL Server 数据类型。数据项于是以 sql:datatype 中指定的类型存储。

sql:datatype 的有效值为 text、ntext、image 和 binary。

示例

若要使用这些示例创建工作示例，必须创建 nwind 虚拟目录（以访问 Northwind 数据库）和 template 类型的虚拟名称。有关创建 nwind 虚拟目录的更多信息，请参见创建 nwind 虚拟目录。

在每一示例中创建工作示例时，使用模板在映射 XDR 架构上指定 XPath 查询。在查询中使用带批注的 XDR 架构有不同的方法，如内嵌架构和 URL 中的架构。有关更多信息，请参见在查询中使用带批注的 XDR 架构。

A. 在特性上指定 dt:type

在此 XDR 架构中，在 OrdDate 和 ShipDate 特性上指定 dt:type。

对于 ReqDate 特性，不指定 XPath 数据类型。因此，XPath 返回从数据库的 RequiredDate 列中检索的 SQL Server datetime 值。

在 OrdDate 特性上指定 date XPath 数据类型。XPath 仅返回从 OrderDate 列检索的值的日期部分（没有时间）。

在 ShipDate 特性上指定 time XPath 数据类型。XPath 仅返回从 ShippedDate 列检索的值的时间部分（没有日期）。

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
        xmlns:dt="urn:schemas-microsoft-com:datatypes"
        xmlns:sql="urn:schemas-microsoft-com:xml-sql">

<ElementType name="Order" sql:relation="Orders">
    <AttributeType name="OID" />
    <AttributeType name="CustID"  />
    <AttributeType name="OrdDate" dt:type="date" />
    <AttributeType name="ReqDate" />
    <AttributeType name="ShipDate" dt:type="time" />

    <attribute type="OID" sql:field="OrderID" />
    <attribute type="CustID" sql:field="CustomerID" />
    <attribute type="OrdDate" sql:field="OrderDate" />
    <attribute type="ReqDate" sql:field="RequiredDate" />
    <attribute type="ShipDate" sql:field="ShippedDate" />
</ElementType>
</Schema>

在架构上测试示例 XPath 查询

  1. 将架构 (MySchema.xml) 保存在与已经创建的 template 虚拟名称相关联的目录中（或其中一个子目录中，在此情况下必须在 mapping-schema 特性中指定相对路径）。

  2. 创建下面的模板 (MySchemaT.xml) 并将其保存在与 template 虚拟名称相关联的目录中：
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:xpath-query mapping-schema="MySchema.xml">
    /Order
  </sql:xpath-query>
</ROOT>
  3. 下面的 URL 执行模板：
    http://IISServer/VirtualRoot/template/MySchemaT.xml

下面是部分结果集：

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <Order OID="10248" CustID="VINET" OrdDate="1996-07-04"
                                  ReqDate="1996-08-01T00:00:00"
                                  ShipDate="00:00:00" />
  <Order OID="10249" CustID="TOMSP" OrdDate="1996-07-05"
                                  ReqDate="1996-08-16T00:00:00"
                                  ShipDate="00:00:00" />
   ...
</ROOT>
B. 在特性上指定 sql:datatype

在下例中，使用 sql:datatype 标识 Photo 列的 SQL Server 数据类型。

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
        xmlns:dt="urn:schemas-microsoft-com:datatypes"
        xmlns:sql="urn:schemas-microsoft-com:xml-sql">

<ElementType name="Employee" sql:relation="Employees">
    <AttributeType name="EID" />
    <AttributeType name="fname" />
    <AttributeType name="lname" />
    <AttributeType name="photo"  />

    <attribute type="EID" sql:field="EmployeeID" />
    <attribute type="fname" sql:field="FirstName" />
    <attribute type="lname" sql:field="LastName" />
    <attribute type="photo" sql:field="Photo" sql:datatype="image" />
</ElementType>
</Schema>

在架构上测试示例 XPath 查询

  1. 将架构 (MySchema.xml) 保存在与已经创建的 template 虚拟名称相关联的目录中（或其中一个子目录中，在此情况下必须在 mapping-schema 特性中指定相对路径）。

  2. 创建下面的模板 (Schema19T.xml) 并将其保存在与 template 虚拟名称相关联的目录中：
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:xpath-query mapping-schema="MySchema.xml">
    /Employee[@EID="1"]
  </sql:xpath-query>
</ROOT>
  3. 下面的 URL 执行模板：
    http://IISServer/VirtualRoot/template/MySchemaT.xml

下面是部分结果集：

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
    <Employee EID="1" fname="Nancy" lname="Davolio"
              photo="Binary base 64 image returned here"/>
</ROOT>

请参见

用于 SQL Server 的 IIS 虚拟目录管理

使用 XPath 查询

使用 HTTP 访问 SQL Server

使用 HTTP 执行模板文件


使用 sql:use-cdata 创建 CDATA 节

在 XML 中，CDATA 节用于转义包含本应被视为标记的字符的文本块。

Microsoft® SQL Server™ 数据可能包含 XML 语法分析器所认为的特殊字符，例如，字符 <、>、<=、& 被当作标记字符处理。若要消除含有被当作标记字符处理的特殊字符的 SQL Server 数据，可将这些数据包含在一个 CDATA 节中。此 CDATA 节中的文本被当作纯文本处理。

sql:use-cdata 批注用于指定是否将 SQL Server 返回的数据包含在一个 CDATA 节中。使用 sql:use-cdata 批注指明 sql:field 指定的列中的值是否应包含在 CDATA 节中。sql:use-cdata 批注可在 <ElementType> 或 <element> 上指定并取布尔值 (0 = FALSE, 1 = TRUE)。sql:use-cdata 不能与 sql:url-encode 一起使用，也不能在 ID、IDREF、IDREFS、NMTOKEN 或 NMTOKENS 这些特性类型上使用。

示例

若要使用这些示例创建工作示例，必须创建 nwind 虚拟目录（以访问 Northwind 数据库）和 template 类型的虚拟名称。有关创建 nwind 虚拟目录的更多信息，请参见创建 nwind 虚拟目录。

在每一示例中创建工作示例时，使用模板在映射 XDR 架构上指定 XPath 查询。在查询中使用带批注的 XDR 架构有不同的方法，如内嵌架构和 URL 中的架构。有关更多信息，请参见在查询中使用带批注的 XDR 架构。

A. 在元素上指定 sql:use-cdata

在下面的架构中，将 <ProductName> 元素的 sql:use-cdata 设置为 1（TRUE）。结果将在 CDATA 节中返回 <ProductName> 的数据。

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
   xmlns:dt="urn:schemas-microsoft-com:datatypes"
   xmlns:sql="urn:schemas-microsoft-com:xml-sql">
   <ElementType name="ProductName" content="textOnly" />
   <ElementType name="Products" >
      <element type="ProductName" sql:use-cdata="1"  />
   </ElementType>
</Schema>

在架构上测试示例 XPath 查询

  1. 将架构 (MySchema.xml) 保存在与已经创建的 template 虚拟名称相关联的目录中（或其中一个子目录中，在此情况下必须在 mapping-schema 特性中指定相对路径）。

  2. 创建下面的模板 (MySchemaT.xml) 并将其保存在与 template 虚拟名称相关联的目录中：
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:xpath-query mapping-schema="MySchema.xml">
    /Products
  </sql:xpath-query>
</ROOT>
  3. 下面的 URL 执行模板：
    http://IISServer/VirtualRoot/template/MySchemaT.xml

下面是部分结果集：

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <Products>
    <ProductName>
      <![CDATA[Alice Mutton]]>
    </ProductName>
  </Products>
</ROOT>

请参见

用于 SQL Server 的 IIS 虚拟目录管理

使用 XPath 查询

使用 HTTP 访问 SQL Server

使用 HTTP 执行模板文件


使用 sql:url-encode 请求对 BLOB 数据的 URL 引用

在带批注的 XDR 架构中，当某个特性（或元素）映射到 Microsoft® SQL Server™ BLOB 列时，在 XML 中，数据将以 Base 64 编码格式返回。有关 SQL Server 数据类型和相应的 XML 数据类型的描述，请参见数据类型强制。

如果希望返回对数据的引用 (URI)，以便稍后可用于检索二进制格式的 BLOB 数据，可指定 sql:url-encode 批注。

指定 sql:url-encode 批注以指出应返回字段的 URL 而不是字段的值。sql:url-encode 依靠主键在 URL 内生成单独选择。使用 sql:key-fields 批注可指定主键。有关更多信息，请参见使用 sql:key-fields 标识键列。

sql:url-encode 批注取布尔值 (0 = FALSE, 1 = TRUE)。sql:url-encode 不能与 sql:use-cdata 一起使用，也不能在 ID、IDREF、IDREF、NMTOKEN 或 NMTOKENS 这些特性类型上使用。

示例

若要使用这些示例创建工作示例，必须创建 nwind 虚拟目录（以访问 Northwind 数据库）和 template 类型的虚拟名称。 有关创建 nwind 虚拟目录的更多信息，请参见创建 nwind 虚拟目录。

在每一示例中创建工作示例时，使用模板在映射 XDR 架构上指定 XPath 查询。在查询中使用带批注的 XDR 架构有不同的方法，如内嵌架构和 URL 中的架构。有关更多信息，请参见在查询中使用带批注的 XDR 架构。

A. 指定 sql:url-encode 以获得对 BLOB 数据的 URL 引用

在下例中，映射架构在 Photo 特性上指定 sql:url-encode 来检索对职员照片的 URI 引用（而不是检索 Base 64 编码格式的二进制数据）。

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
   xmlns:dt="urn:schemas-microsoft-com:datatypes"
   xmlns:sql="urn:schemas-microsoft-com:xml-sql">
   <ElementType name="Employee" sql:relation="Employees"
                 sql:key-fields="EmployeeID" >
      <AttributeType name="EmployeeID" />
      <AttributeType name="Photo" />

      <attribute type="EmployeeID" />
      <attribute type="Photo"  sql:url-encode="1" />
   </ElementType>
</Schema>

在架构上测试示例 XPath 查询

  1. 将架构 (MySchema.xml) 保存在与已经创建的 template 虚拟名称相关联的目录中（或其中一个子目录中，在此情况下必须在 mapping-schema 特性中指定相对路径）。

  2. 创建下面的模板 (MySchemaT.xml) 并将其保存在与 template 虚拟名称相关联的目录中：
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:xpath-query mapping-schema="MySchema.xml">
    /Employee[@EmployeeID=1]
  </sql:xpath-query>
</ROOT>
  3. 下面的 URL 执行模板：
    http://IISServer/VirtualRoot/template/MySchemaT.xml

下面是结果：

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
    <Employee EmployeeID="1"
              Photo="dbobject/Employees[@EmployeeID="1"]/@Photo" />
</ROOT>

请参见

用于 SQL Server 的 IIS 虚拟目录管理

使用 XPath 查询

使用 HTTP 访问 SQL Server

使用 HTTP 执行模板文件


使用 sql:overflow-field 检索未用完的数据

当使用 OPENXML 将记录从 XML 文档插入数据库时，源 XML 文档中所有未用完的数据都可存储在某列中。当使用带批注架构从数据库中检索数据时，可指定 sql:overflow-field 特性标识表中存储溢出数据的列。

之后，可以通过下列方式检索这些数据：

  • 将溢出列中存储的特性添加到包含 sql:overflow-field 批注的元素中。

  • 存储在数据库中溢出列的子元素及其后代作为子元素添加，并放在架构中显式指定的内容之后（不保留顺序）。
示例

若要使用这些示例创建工作示例，必须创建 nwind 虚拟目录（以访问 Northwind 数据库）和 template 类型的虚拟名称。有关创建 nwind 虚拟目录的更多信息，请参见创建 nwind 虚拟目录。

在每一示例中创建工作示例时，使用模板在映射 XDR 架构上指定 XPath 查询。在查询中使用带批注的 XDR 架构有不同的方法，如内嵌架构和 URL 中的架构。有关更多信息，请参见在查询中使用带批注的 XDR 架构。

A. 为 XDR 架构中的 <ElementType> 指定 sql:overflow-field

下例假设该表已存在：

CREATE TABLE Customers2 (
   CustomerID       VARCHAR(10),
   ContactName    VARCHAR(30),
   OverflowData    NVARCHAR(200))
GO
INSERT INTO Customers2 VALUES (
      'ALFKI',
      'Joe',
       N'<xyz><address>111 Maple, Seattle</address></xyz>')
GO

在下例中，映射架构检索存储在 Customers2 表的 OverflowData 列中的未用完数据。在 <ElementType> 上指定 sql:overflow-field 特性。

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
        xmlns:dt="urn:schemas-microsoft-com:datatypes"
        xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <ElementType name="Customers2" sql:overflow-field="OverflowData" >
    <AttributeType name="CustomerID" />
    <AttributeType name="ContactName" />

    <attribute type="CustomerID" />
    <attribute type="ContactName"/>
  </ElementType>
</Schema>

在架构上测试示例 XPath 查询

  1. 将架构 (MySchema.xml) 保存在与已经创建的 template 虚拟名称相关联的目录中（或其中一个子目录中，在此情况下必须在 mapping-schema 特性中指定相对路径）。

  2. 创建下面的模板 (MySchemaT.xml) 并将其保存在与 template 虚拟名称相关联的目录中。此模板中的查询选择 CustomerID 为 ALFKI 的客户。
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:xpath-query mapping-schema="MySchema.xml">
    Customers2
  </sql:xpath-query>
</ROOT>
  3. 下面的 URL 执行模板：
    http://IISServer/VirtualRoot/template/MySchemaT.xml

下面是部分结果集：

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <Customers2 CustomerID="ALFKI" ContactName="Joe">
    <address>111 Maple, Seattle</address>
  </Customers2>
</ROOT>

请参见

用于 SQL Server 的 IIS 虚拟目录管理

使用 XPath 查询

使用 HTTP 访问 SQL Server

使用 HTTP 执行模板文件


在 XDR 架构中指定特性的默认值

在数据库中可为列指派默认值。同样，在 XDR 架构中也可为特性设置默认值（在 XDR 架构中不能为元素指派默认值）。XDR 架构允许 <AttributeType> 上的 default 特性规范。

如果与特性相关联的列值为 NULL，则不返回那个元素实例的该特性。但如果在 <AttributeType> 上指定 default 特性，则特性将以指定的默认值返回。

例如，在将数据从数据库析取到 XML 文档时，如果缺少某个特性值，则使用 XDR 架构中该特性的默认值。

说明 默认值也许不出现在返回的文档中，而是在特性不存在时由验证语法分析器使用。

如果使用的语法分析器识别架构，则使用默认值。比如对于 MSXML 语法分析器，必须确保将 resolveExternals 标记设置为 TRUE（默认值），这样语法分析器才会提取架构。经过分析后，不论为其指定了默认值的特性是否包含在 XML 文档中，每个实例都拥有该特性。DOM 提供默认值。

示例

若要使用这些示例创建工作示例，必须创建 nwind 虚拟目录（以访问 Northwind 数据库）和 template 类型的虚拟名称。有关创建 nwind 虚拟目录的更多信息，请参见创建 nwind 虚拟目录。

在每一示例中创建工作示例时，使用模板在映射 XDR 架构上指定 XPath 查询。在查询中使用带批注的 XDR 架构有不同的方法，如内嵌架构和 URL 中的架构。有关更多信息，请参见在查询中使用带批注的 XDR 架构。

A. 在 XDR 架构中指定特性的默认值

在下例中，为特性 Title 提供了默认值 XYZ。当检索职员记录时，为没有职务的职员指派默认值。

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
        xmlns:dt="urn:schemas-microsoft-com:datatypes"
        xmlns:sql="urn:schemas-microsoft-com:xml-sql">

<ElementType name="Employees" >
    <AttributeType name="EID" sql:field="EmployeeID"/>
    <AttributeType name="FirstName" />
    <AttributeType name="LastName" />
    <AttributeType name="Title" default="XYZ"/>

    <attribute type="EID" sql:field="EmployeeID" />
    <attribute type="FirstName" />
    <attribute type="LastName" />
    <attribute type="Title"  />
</ElementType>
</Schema>

在架构上测试示例 XPath 查询

  1. 将架构 (MySchema.xml) 保存在与已经创建的 template 虚拟名称相关联的目录中（或其中一个子目录中，在此情况下必须在 mapping-schema 特性中指定相对路径）。

  2. 创建下面的模板 (MySchemaT.xml) 并将其保存在与 template 虚拟名称相关联的目录中。此模板中的查询选择 CustomerID 为 ALFKI 的客户。
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:xpath-query mapping-schema="MySchema.xml">
    /Employees
  </sql:xpath-query>
</ROOT>
  3. 下面的 URL 执行模板：
    http://IISServer/VirtualRoot/template/MySchemaT.xml

请参见

用于 SQL Server 的 IIS 虚拟目录管理

使用 XPath 查询

使用 HTTP 访问 SQL Server

使用 HTTP 执行模板文件


在查询中使用带批注的 XDR 架构

可以使用下面的方法在带批注的架构上指定从数据库中检索数据的查询。

  • 在模板中指定对 XDR 架构的 XPath 查询

    <sql:xpath-query> 元素使您得以在由带批注的架构定义的 XML 视图上指定 XPath 查询。通过使用 <sql:xpath-query> 元素的 mapping-schema 特性，可以识别要对其执行 XPath 查询的带批注的架构。

    模板是包含一个或多个查询的有效 XML 文档。FOR XML 和 XPath 查询返回文档片段。模板相当于所得到的文档碎片的容器（模板提供了指定单个顶层元素的方法）。

    本主题中的示例使用模板，在批注架构上指定从数据库中检索数据的 XPath 查询。

    有关模板的更多信息，请参见使用 URL 执行模板文件。

  • 内嵌映射架构

    带批注的架构可以直接包含在模板中。sql:is-mapping-schema 批注用于指定内嵌映射架构。sql:is-mapping-schema 取布尔值 (0 = FALSE, 1 = TRUE）。sql:is-mapping-schema 在模板中的 <Schema> 元素上指定。

    sql:id 特性唯一标识包含它的元素。sql:id 是 ID 类型的特性并在 <Schema> 元素上指定。于是，赋给 sql:id 的值用于通过使用 <sql:xpath-query> 中的 mapping-schema 特性引用内嵌映射架构。

    例如，下例指定一个含有内嵌映射架构的模板。

    <ROOT     xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <Schema xmlns="urn:schemas-microsoft-com:xml-data"

    sql:id="MyMappingSchema"
    sql:is-mapping-schema="1">

    <ElementType name="Employees" >
      <AttributeType name="EmployeeID" />
      <AttributeType name="FirstName" />
      <AttributeType name="LastName" />

      <attribute type="EmployeeID" />
      <attribute type="FirstName" />
      <attribute type="LastName" />
    </ElementType>
  </Schema>

<sql:xpath-query mapping-schema="#MyMappingSchema">
  Employees
</sql:xpath-query>
</ROOT>

    为了举例说明，将该模板存储在虚拟根目录的模板子目录中，且文件名为 InlineSchemaTemplate.xml。

    下面的 URL 执行模板：

    http://IISServer/VirtualRoot/template/InlineSchemaTemplate.xml

    在此 URL 中，template 是 template 类型的虚拟名称（通过使用用于 SQL Server 的 IIS 虚拟目录管理实用工具创建），后面是模板文件名。

  • URL 中的映射架构

    可以直接在 URL 中指定对带批注的架构的XPath 查询。为此，可创建 schema 类型的虚拟名称，并在 URL 中指定对带批注的架构的 XPath 查询。

    例如，考察下面带批注的架构：

    <?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
        xmlns:dt="urn:schemas-microsoft-com:datatypes"
        xmlns:sql="urn:schemas-microsoft-com:xml-sql">

  <ElementType name="Customer" sql:relation="Customers" >
    <AttributeType name="CustomerID" />
    <AttributeType name="ContactName" />
    <AttributeType name="Phone" />

    <attribute type="CustomerID" />
    <attribute type="ContactName" />
    <attribute type="Phone" />
  </ElementType>
</Schema>

    为了举例说明，将此 XDR 架构存储在虚拟根目录的架构子目录中，且文件名是 Schema2.xml。

    可以直接在 URL 中指定对带批注的架构的 XPath 查询：

    http://IISServer/VirtualRoot/schema/Schema2.xml/Customer[@CustomerID="ALFKI"]

    在此 URL 中，schema 是 schema 类型的虚拟名称（通过使用用于 SQL Server 的 IIS 虚拟目录管理实用工具创建）。Schema2.xml 是带批注的架构文件，其后是一个 XPath 查询，该查询请求 CustomerID 为 ALFKI 的所有客户。

请参见

用于 SQL Server 的 IIS 虚拟目录管理

使用 XPath 查询

使用 HTTP 访问 SQL Server

使用 HTTP 执行模板文件


架构高速缓存

架构高速缓存可显著提高 XPath 查询的性能。当对带批注的 XDR 架构执行 XPath 查询时，架构存储在内存中，而必要的数据结构内置在内存中。如果设置了架构高速缓存，架构仍保留在内存中，因而提高了后续 Xpath 查询的性能。

可通过在注册表中添加下列键来设置架构高速缓存的大小：

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Client\SQLXMLX\SchemaCacheSize。

根据可用内存和要使用的架构数设置架构大小。默认的架构高速缓存大小为 31。如果设置更高的架构高速缓存大小，需使用更多的内存。因此，如果架构访问速度慢，可增加高速缓存大小，如果内存少则可减小高速缓存的大小。

出于性能方面的考虑，建议将架构高速缓存的大小设得比通常所用的映射架构数多。当架构数增加时，如果架构高速缓存的大小比所拥有的架构数少，性能会降低。

说明 在开发期间，建议不要对架构进行高速缓存，因为架构的更改不会在大约 2 分钟的时间内在高速缓存中反映出来。

请参见

用于 SQL Server 的 IIS 虚拟目录管理

使用 XPath 查询

使用 HTTP 访问 SQL Server

XML 错误信息


使用 XPath 查询

Microsoft® SQL Server™ 2000 支持带批注的 XDR 架构，使您得以创建存储在数据库中的关系数据的 XML 视图。可使用 XPath 语言的子集查询带批注的 XDR 架构所创建的 XML 视图。

XPath 查询可以被指定为 URL 的一部分或包含在模板中。映射架构确定了这一所得到的文档碎片的结构，而且值是从数据库中检索。此过程在概念上类似于使用 CREATE VIEW 语句创建视图并编写在其上执行的 SQL 查询。

说明 为理解 XPath 查询，一定要熟悉模板的概念（有关更多信息，请参见使用 XML 模板）、对 SQL Server 的 HTTP 访问（有关更多信息，请参见使用 HTTP 访问 SQL Server)、映射架构（有关更多信息，请参见使用带批注的 XDR 架构创建 XML 视图）和 World Wide Web Consortium (W3C) 定义的 XPath 标准。

XML 文档包括许多节点，如元素节点、特性节点、文本节点等。例如，考察下面的 XML 文档：

<root>
  <Customer cid= "C1" name="Janine" city="Issaquah">
      <Order oid="O1" date="1/20/1996" amount="3.5" />
      <Order oid="O2" date="4/30/1997" amount="13.4">Customer was
          very satisfied</Order>
   </Customer>
   <Customer cid="C2" name="Ursula" city="Oelde" >
      <Order oid="O3" date="7/14/1999" amount="100" note="Wrap it blue white red">
          <Urgency>Important</Urgency>
      </Order>
      <Order oid="O4" date="1/20/1996" amount="10000"/>
   </Customer>
</root>

在该文档中，Customer 为元素节点，cid 为特性节点而 Important 为文本节点。

Xpath（XML Path 语言）是一种图形导航语言。XPath 用于从 XML 文档中选择节点集。每个 XPath 运算符都根据前面的 XPath 运算符所选择的节点集选择节点集。例如，给定一组 <Customer> 节点，XPath 可选择 date 特性值为 7/14/1999 的所有 <Order> 节点。所得到的节点集包含订购日期为 7/14/1999 的所有订单。

说明 XPath 语言由 W3C 定义为标准导航语言。W3C 于 1999 年 10 月 8 日提出的 XPath 语言规范、XML Path 语言 (XPath) 1.0 版可在 W3C Web 站点上找到，网址为：http://www.w3.org/TR/1999/PR-xpath-19991008.html。SQL Server 2000 中实现的是该规范的子集。有关更多信息，请参见 XPath 查询的使用准则。

支持的功能

下表显示 SQL Server 2000 中实现的 XPath 语言的功能。

功能 | 项目 | 到示例查询的链接
轴 | attribute、child、parent 和 self 轴 | 在 XPath 查询中指定轴
包括连续谓词和嵌套谓词在内的布尔值谓词 |  | 在 XPath 查询中指定算术运算符
所有关系运算符 | =, !=, <, <=, >, >= | 在 XPath 查询中指定关系运算符
算术运算符 | +, -, *, div | 在 Xpath 查询中指定算术运算符
显式转换函数 | number()、string()、Boolean() | 在 XPath 查询中指定显式转换
布尔运算符 | AND, OR | 在 XPath 查询中指定布尔运算符
布尔函数 | true()、false()、not() | 在 XPath 查询中指定布尔函数
XPath 变量 |  | 在 XPath 查询中指定 XPath 变量

不支持的功能

下表显示 SQL Server 2000 中没有实现的 XPath 语言的功能。

功能 | 项目
轴 | ancestor、ancestor-or-self、descendant、descendant-or-self (//)、following、following-sibling、namespace、preceding、preceding-sibling
数值谓词 |
算术运算符 | mod
节点函数 | ancestor、ancestor-or-self、descendant、descendant-or-self (//)、following、following-sibling、namespace、preceding、preceding-sibling
字符串函数 | string()、concat()、starts-with()、contains()、substring-before()、substring-after()、substring()、string-length()、normalize()、translate()
布尔函数 | lang()
数字函数 | sum()、floor()、ceiling()、round()
Union 运算符 | |

指定 XPath 查询

XPath 查询可直接在 URL 中指定，也可在 URL 指定的模板中指定。参数可传递到直接在 URL 指定的 XPath 查询，也可传递到使用 XPath 变量的模板中指定的 XPath 查询。

URL 中的 XPath 查询

直接在 URL 中指定 Xpath 查询，例如：

http://IISServer/VirtualRoot/SchemaVirtualName/SchemaFile/XPathQuery[?root=ROOT]

指定 root 参数以提供单个顶层元素。可以为该参数指定任何值。如果查询仅返回一个元素（或者如果想接收顶层节点的集合），则不必指定该参数。

URL 中的 SchemaVirtualName 是使用用于 SQL Server 的 IIS 虚拟目录管理实用工具创建的 schema 类型的虚拟名称。有关更多信息，请参见用于 SQL Server 的 IIS 虚拟目录管理。

当在 URL 中指定 XPath 查询时，注意下面 URL 特有的行为：

  • XPath 可能包含在 URL 中有特殊含义的字符，如 # 或 +。使用 URL 百分比编码转义这些字符，或在模板中指定 Xpath。例如，URL http://IISServer/VirtualRoot/VirtualName/SchemaFile/Customers[@CustomerID="#"] 在 # 符号处截断，导致一个无效的 Xpath。

  • 与特殊文件路径相似的 XPath 表达式（如 .. 或 //）被某些浏览器解释，并在将 URL 传递到服务器之前对其进行修改。因此，包含这些表达式的 XPath 可能不会像在 URL 中预期的那样工作。例如：
    • URL http://IISServer/VirtualRoot/VirtualName/SchemaFile/Customers/.. 可能会被浏览器转换为 http://IIServer/VirtualRoot/VirtualName/SchemaFile/，这是无效的 Xpath。

    • URL http://IISServer/VirtualRoot/VirtualName/SchemaFile//Customers 可能会被浏览器转换为 http://IISServer/VirtualRoot/VirtualName/SchemaFile/Customers，这是与原来不同的 Xpath。
模板中的 XPath 查询

可在模板中写入 XPath 查询并在 URL 中指定模板。例如，下面是一个带 XPath 查询的模板：

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:xpath-query mapping-schema="FilePath/AnnotatedSchemaFile.xml">
    Specify the XPath query
  </sql:xpath-query>
</ROOT>

将模板文件存储在创建 template 类型的虚拟名称时所指定的目录中。有关配置虚拟根的更多信息，请参见使用用于 SQL Server 的 IIS 虚拟目录管理实用工具。

下面的 URL 执行模板：

http://IISServer/VirtualRoot/VirtualName/TemplateFile.xml

在 URL 中指定的 VirtualName 是 template 类型。

说明 对于在 URL 中直接指定的 XPath 查询，不支持命名空间。如果希望在 XPath 查询中使用命名空间，则应使用 template。有关模板的更多信息，请参见使用 URL 执行模板文件。

当在模板中指定 XPath 查询时，注意下列行为：

  • XPath 可能包含在 XML（模板为 XML 文档）中有特殊含义的字符，如 < 或 & 等。必须使用 XML & 编码方式对这些字符进行转义，或在 URL 中指定 XPath。

请参见

使用 FOR XML 检索 XML 文档

使用 HTTP 访问 SQL Server

用于 SQL Server 的 IIS 虚拟目录管理

XML 错误信息


XPath 查询的使用准则

Microsoft® SQL Server™ 2000 实现的是 World Wide Web Consortium (W3C) XPath 规范的子集，该规范位于 http://www.w3.org/TR/1999/PR-xpath-19991008.html。SQL Server 2000 内实现的 XPath 查询在下列方面不同于 W3C 规范：

  • 根查询

    SQL Server 2000 不支持根查询 (/)。每个 XPath 查询必须从架构的顶层 <ElementType> 开始。

  • 报告错误

    W3C XPath 规范未定义错误条件。没有选择任何节点的 XPath 查询将返回空节点集。在 SQL Server 2000 中，查询可能返回多种类型的错误信息。有关更多信息，请参见 XPath 查询中的错误。

  • 文档顺序

    在 SQL Server 2000 中，文档排序并非总是确定的。因此，未实现使用文档顺序（如 following）的数字谓词和轴。

    缺少文档顺序也意味着只有当节点映射到单行中的单列时，才能对该节点的字符串取值。带有子元素的元素或 IDREFS 或 NMTOKENS 节点无法转换为字符串。

    说明 在某些情况下，key-fields 批注或来自 relationship 批注的键会产生确定的文档顺序。但是，这并不是这些批注的主要作用。有关更多信息，请参见使用 sql:key-fields 标识键列和使用 <sql:relationship> 指定关系。

  • 数据类型

    SQL Server 2000 对 XPath string、number 及 boolean 数据类型的实现有一些限制。有关更多信息，请参见 XPath 数据类型。

  • 矢量积查询

    SQL Server 2000 不支持矢量积 XPath 查询，如 Customer[Order/@OrderDate=Order/@ShippedDate]。该查询选择 Order 的 OrderDate 等于任何 Order 的 ShippedDate的所有 Customer。

    但是，SQL Server 2000 确实支持某些查询，如 Customer[Order[@OrderDate=@ShippedDate]]。该查询选择 Order 的 OrderDate 等于它的 ShippedDate 的所有 Customers。

请参见

使用 XPath 查询


指定位置路径

XPath 查询是以表达式的形式指定的。有各种表达式。位置路径是一种表达式，用以选择相对于上下文节点的节点集。位置路径表达式的求值结果是节点集。

位置路径的类型

位置路径可以是下面的形式：

  • 绝对位置路径

    绝对位置路径以文档的根节点开始，由斜杠 (/) 组成，后面可以是相对位置路径。斜杠 (/) 选定文档的根节点。

  • 相对位置路径

    相对位置路径以文档的上下文节点开始，由斜杠 (/) 所分开的一个或多个位置步骤序列组成。每个步骤都选定相对于上下文节点的节点集。初始步骤序列选定相对于上下文节点的节点集。节点集中的每个节点都用作后续步骤的上下文节点。由后续步骤标识的节点集联接在一起。例如，child::Order/child::OrderDetail 选定上下文节点的 <Order> 子元素的 <OrderDetail> 子元素。

    说明 在此次实现的 Xpath 中，每个 XPath 查询都从根上下文开始，即使 XPath 不是显式绝对位置路径。例如，从 Customer 开始的 XPath 查询被视为 /Customer。在 XPath 查询 Customer[Order] 中，Customer 从根上下文开始，但 Order 从 Customer 上下文开始。有关更多信息，请参见 XPath 查询的使用准则。

位置步骤

（绝对或相对）位置路径由包含下面三部分的位置步骤组成：

  • 轴

    轴指定位置步骤选定的节点与上下文节点之间的树关系。支持 parent、child、attribute 及 self 轴。如果在位置路径中指定 child 轴，查询选定的所有节点都将是上下文节点的子节点。如果指定 parent 轴，选定的节点将是上下文节点的父节点。如果指定 attribute 轴，选定的节点是上下文节点的特性。

  • 节点测试

    节点测试指定位置步骤选定的节点类型。每个轴（child、parent、attribute 和 self）都具有主要节点类型。对于 attribute 轴，主要节点类型是 <attribute>。对于 parent、child 和 self 轴，主要节点类型是 <element>。

    例如，如果位置路径指定 child::Customer，则将选定上下文节点的 <Customer> 子元素。因为 child 轴以 <element> 为其主要节点类型，而且如果 Customer 是 <element> 节点，则节点测试 Customer 为 TRUE。

  • 选择谓词（零个或多个）

    谓词围绕着轴筛选节点集。在 XPath 表达式中指定选择谓词与在 SELECT 语句中指定 WHERE 子句相似。谓词在括号中指定。应用在选择谓词中指定的测试将对节点测试返回的节点进行筛选。对于要筛选的节点集中的每个节点，在对谓词表达式取值时将此节点作为上下文节点，将节点集中的节点数作为上下文大小。如果谓词表达式对此节点取值为 TRUE，则此节点将包括在最后所得到的节点集中。

    位置步骤的语法是用两个冒号 (::) 分开的轴名和节点测试，后面是分别放在方括号中的零个或多个表达式。例如，在 XPath 表达式（位置路径）child::Customer[@CustomerID='ALFKI'] 中，选定上下文节点的所有 <Customer> 子元素。然后将谓词中的测试应用于节点集，将只返回 CustomerID 特性的特性值为 'ALFKI' 的 <Customer> 元素节点。


指定轴

轴指定位置步骤选定的节点与上下文节点之间的树关系。支持下列轴：

  • child

    包含上下文节点的子节点。

    下面的 XPath 表达式（位置路径）从当前的上下文节点中选定所有 <Customer> 子节点：

    child::Customer

    在此 XPath 查询中，child 是轴。而 Customer 是节点测试。

  • parent

    包含上下文节点的父节点。

    下面的 XPath 表达式选定 <Order> 子节点的所有 <Customer> 父节点：

    child::Customer/child::Order[parent::Customer/@customerID="ALFKI"]

    这与指定 Child::Customer 相同。在此 Xpath 查询中，child 和 parent 是轴。而 Customer 和 Order 是节点测试。

  • attribute

    包含上下文节点的特性。

    此 XPath 表达式选定上下文节点的 CustomerID 特性：

    attribute::CustomerID
  • self

    包含上下文节点本身。

    如果当前节点是 <Order> 节点，则下面的 XPath 表达式选定该节点：

    self::Order

    在此 XPath 查询中，self 是轴，而 Order 是节点测试。


在位置路径中指定节点测试

节点测试指定位置步骤选定的节点类型。每个轴（child、parent、attribute 和 self）都具有主要节点类型。对于 attribute 轴，主要节点类型是 <attribute>。对于 parent、child 和 self 轴，主要节点类型是 <element>。

说明 不支持 * 通配符节点测试（如 child::*）。

节点测试：示例 1

位置路径 child::Customer 选定上下文节点的 Customer 子元素。

在此例中，child 是轴，Customer 是节点测试。child 轴的主要节点类型是 <element>。因此，如果 <Customer> 节点是 <element> 节点，该节点测试将为 TRUE。如果上下文节点没有 <Customer> 子节点，则返回空节点集。

节点测试：示例 2

位置路径 attribute::CustomerID 选定上下文节点的 CustomerID 特性。

在此例中，attribute 是轴，CustomerID 是节点测试。attribute 轴的主要节点类型是 <attribute>。因此，如果 CustomerID 是 <attribute> 节点，该节点测试为 TRUE。如果上下文节点中不含 CustomerID，则返回空节点集。

说明 在此次实现的 Xpath 中，如果位置步骤引用的 <element> 或 <attribute> 类型在架构中没有声明，则生成错误。这与 MSXML 中实现的 XPath 不同，后者返回空节点集。

轴的缩略语法

支持下面的位置路径缩略语法：

  • attribute::可以缩略为 @。

    位置路径 Customer[@CustomerID="ALFKI"] 与 child::Customer[attribute::CustomerID="ALFKI"] 相同。

  • child::可以在位置步骤中省略。

    因此，child 是默认轴。位置路径 Customer/Order 与 child::Customer/child::Order 相同。

  • self::node() 可缩略为一个句点 (.)，而 parent::node() 可缩略两个句点 (..)。


在位置路径中指定选择谓词

谓词围绕着轴筛选节点集（就象 SELECT 语句中的 WHERE 子句）。谓词在括号中指定。对于要筛选的节点集中的每个节点，在对谓词表达式取值时将此节点作为上下文节点，将节点集中的节点数作为上下文大小。如果谓词表达式对此节点取值为 TRUE，则此节点将包括在最后所得到的节点集中。

XPath 还允许基于位置进行筛选。取值为数字的谓词表达式选择按顺序排列的那个节点。例如，位置路径 Customer[3] 返回第三个客户。不支持这些数字谓词。只支持返回布尔结果的谓词表达式。

说明 有关对此 XPath 实现的限制以及它与 W3C 规范之间的差异的信息，请参见 XPath 查询的使用准则。

选择谓词：示例 1

下面的 XPath 表达式（位置路径）从当前的上下文节点中选定 CustomerID 特性值为 ALFKI 的所有 <Customer> 子元素。

/child::Customer[attribute::CustomerID="ALFKI"]

在此 XPath 查询中，child 和 attribute 是轴名。Customer 是节点测试（如果 Customer 是 <element node>，则该测试为 TRUE，因为 <element> 是 child 轴的主要节点类型）。attribute::CustomerID="ALFKI" 是谓词。在该谓词中，attribute 是轴，CustomerID 是节点测试（如果 CustomerID 是上下文节点的特性，该测试为 TRUE，因为 <attribute> 是 attribute 轴的主要节点类型）。

还可以使用缩略语法这样指定 XPath 查询：

/Customer[@CustomerID="ALFKI"]
选择谓词：示例 2

此 XPath 表达式（位置路径）从当前的上下文节点中选定 OrderID 特性值为 1 的所有 <Order> 孙节点：

/child::Customer/child::Order[attribute::OrderID="1"]

在此 XPath 表达式中，child 和 attribute 是轴名。Customer、Order 和 OrderID 是节点测试，attribute::OrderID="1" 是谓词。

还可以使用缩略语法这样指定 XPath 查询：

/Customer/Order[@OrderID="1"]
选择谓词：示例 3

此 XPath 表达式（位置路径）从当前的上下文节点中选定包含一个或多个 <ContactName> 子节点的所有 <Customer> 子节点。

child::Customer[child::ContactName]

下例假定 <ContactName> 是 XML 文档中的 <Customer> 元素的 <child> 元素（称为带批注的 XDR 架构中以元素为中心的映射）。有关更多信息，请参见使用带批注的 XDR 架构创建 XML 视图。

在此 XPath 表达式中，child 是轴名。Customer 是节点测试（如果 Customer 是 <element> 节点，则该测试 TRUE，因为 <element> 是 child 轴的主要节点类型）。child::ContactName 是谓词。在该谓词中，child 是轴，ContactName 是节点测试（如果 ContactName 是 <element> 节点，则该测试为 TRUE）。

该表达式只返回含有 <ContactName> 子元素的上下文节点的 <Customer> 子元素。

还可以使用缩略语法这样指定 XPath 查询：

Customer[ContacName]
选择谓词：示例 4

此 XPath 表达式选定不包含 <ContactName> 子元素的上下文节点的 <Customer> 子元素。

child::Customer[not(child::ContactName)]

下例假定 <ContactName> 是 XML 文档（以元素为中心的映射）中 <Customer> 元素的子元素，而 ContactName 是数据库中的非必需字段。

在下例中，child 是轴。Customer 是节点测试（如果 Customer 是 <element> 节点，则该测试为 TRUE）。not(child::ContactName) 是谓词。在该谓词中，child 是轴，而 ContactName 是节点测试（如果 ContactName 是 <element> 节点，则该测试为 TRUE）。

还可以使用缩略语法这样指定 XPath 路径：

Customer[not(ContactName)]
选择谓词：示例 5

此 XPath 表达式从当前的上下文节点中选定具有 CustomerID 特性的所有 <Customer> 子节点。

child::Customer[attribute::CustomerID]

在此例中，child 是轴，Customer 是测试节点（如果 Customer 是 <element> 节点，则该测试为 TRUE）。attribute::CustomerID 是谓词。在该谓词中，attribute 是轴，CustomerID 是谓词（如果 CustomerID 是 <attribute> 节点，则为 TRUE）。

还可以使用缩略语法这样指定 XPath 查询：

Customer[@CustomerID]

请参见

使用带批注的 XDR 架构创建 XML 视图

使用 FOR XML 检索 XML 文档

使用 HTTP 访问 SQL Server


示例 XPath 查询

本示例 XPath 查询引用下面两个映射架构。映射架构是带批注的简化 XML-Data (XDR) 架构。有关映射架构的更多信息，请参见使用带批注的 XDR 架构创建 XML 视图。

说明 在可以使用 URL 执行示例 XPath 查询前，必须创建虚拟根以访问 Northwind 数据库和 template 及 schema 类型的虚拟名称。有关创建示例 nwind 虚拟目录和虚拟名称的信息，请参见创建 nwind 虚拟目录。有关使用 HTTP 访问 Microsoft® SQL Server™ 的更多信息，请参见使用 HTTP 访问 SQL Server。

有两种方法可对带批注的 XDR 架构执行 XPath 查询：

  • 创建一个模板，在其中包含一个 XPath 查询。然后在 URL（例如 http://IISServer/VirtualRoot/TemplateVirtualName/TemplateFile.xml）中执行该模板。在该模板中，指定将对其执行 XPath 查询的映射架构。在这种情况下，必须将映射架构存储到与 template 类型的虚拟名称相关联的目录（或它的一个子目录，此时将某相对路径指定为模板内 mapping-schema 特性的值）下。

  • 可直接在 URL（例如 http://IISServer/VirtualRoot/SchemaVirtualName/SchemaFile.xml/XpathQuery）中指定 XPath 查询。在这种情况下，必须将架构文件存储到与 schema 类型的虚拟名称相关联的目录下。
示例带批注的 XDR 架构

在本节的所有示例中，为了说明，将在模板中指定 XPath 查询，并使用 HTTP 执行该模板。因此，必须使用此映射架构文件 (SampleSchema1.xml)，它保存在与 template 类型虚拟名称相关联的目录下：

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
        xmlns:dt="urn:schemas-microsoft-com:datatypes"
        xmlns:sql="urn:schemas-microsoft-com:xml-sql">

  <ElementType name="Customer" sql:relation="Customers">
    <AttributeType name="CustomerID" dt:type="id" />
    <AttributeType name="CompanyName" />
    <AttributeType name="ContactName" />
    <AttributeType name="City" />
    <AttributeType name="Fax" />
    <AttributeType name="Orders" dt:type="idrefs"  sql:id-prefix="Ord-" />

    <attribute type="CustomerID" />
    <attribute type="CompanyName" />
    <attribute type="ContactName" />
    <attribute type="City" />
    <attribute type="Fax" />
    <attribute type="Orders" sql:relation="Orders" sql:field="OrderID">
      <sql:relationship
                key-relation="Customers"
                key="CustomerID"
                foreign-relation="Orders"
                foreign-key="CustomerID" />
    </attribute>

    <element type="Order">
      <sql:relationship
               key-relation="Customers"
               key="CustomerID"
               foreign-relation="Orders"
               foreign-key="CustomerID" />
    </element>
  </ElementType>

  <ElementType name="Order" sql:relation="Orders">
    <AttributeType name="OrderID" dt:type="id" sql:id-prefix="Ord-" />
    <AttributeType name="EmployeeID" />
    <AttributeType name="OrderDate" />
    <AttributeType name="RequiredDate" />
    <AttributeType name="ShippedDate" />

    <attribute type="OrderID" />
    <attribute type="EmployeeID" />
    <attribute type="OrderDate" />
    <attribute type="RequiredDate" />
    <attribute type="ShippedDate" />

    <element type="OrderDetail">
      <sql:relationship
                 key-relation="Orders"
                 key="OrderID"
                 foreign-relation="[Order Details]"
                 foreign-key="OrderID" />
    </element>
  </ElementType>

  <ElementType name="OrderDetail" sql:relation="[Order Details]"
                                  sql:key-fields="OrderID ProductID">
    <AttributeType name="ProductID" dt:type="idref"
                                    sql:id-prefix="Prod-" />
    <AttributeType name="UnitPrice"/>
    <AttributeType name="Quantity" />

    <attribute type="ProductID" />
    <attribute type="UnitPrice" sql:field="UnitPrice" />
    <attribute type="Quantity" />

    <element type="Discount"  sql:field="Discount"/>
  </ElementType>

  <ElementType name="Discount" dt:type="string"
                               sql:relation="[Order Details]"/>

<ElementType name="Employee" sql:relation="Employees">
    <AttributeType name="EmployeeID" />
    <AttributeType name="LastName" />
    <AttributeType name="FirstName" />
    <AttributeType name="Title" />

    <attribute type="EmployeeID" />
    <attribute type="LastName" />
    <attribute type="FirstName" />
    <attribute type="Title" />
</ElementType>
</Schema>

说明

按查询所执行的 XPath 操作类型将示例查询分组。


在 XPath 查询中指定轴

以下示例显示如何在 XPath 查询中指定轴。这些示例中的 XPath 查询都在 SampleSchema1.xml 中所包含的映射架构上指定。有关此示例架构的信息，请参见示例 XPath 查询。

示例
A. 检索上下文节点的子元素

此 XPath 查询选定上下文节点的所有 <Customer> 子元素：

/child::Employee

在此查询中，child 是轴，Customer 是节点测试（如果 Customer 是 <element> 节点，则该测试为 TRUE，因为 <element> 是与 child 轴相关联的主要节点类型）。

child 是默认轴。因此，可将该查询编写为：

/Employee

在映射架构上测试 XPath 查询

  1. 创建下面的模板 (MyTemplate.xml) 并将其保存在与 template 虚拟名称相关联的目录中。
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:xpath-query mapping-schema="SampleSchema2.xml">
    /Employee
  </sql:xpath-query>
</ROOT>
  2. 下面的 URL 执行模板：
    http://IISServer/VirtualRoot/template/MyTemplate.xml

    可直接在 URL 中指定 XPath 查询：

    http://IISServer/nwind/schema/SampleSchema1.xml/child::Customer?root=root

    虚拟名称 schema 是 schema 类型。架构文件存储在与 schema 类型虚拟名称相关联的目录下。root 参数用于为所得到的 XML 文档指定顶层元素（root 可为任意值）。

    下面是模板执行的部分结果集：

    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <Employee EmployeeID="1" LastName="Davolio"
            FirstName="Nancy" Title="Sales Representative" />
  <Employee EmployeeID="2" LastName="Fuller"
            FirstName="Andrew" Title="Vice President, Sales" />
   ...
</ROOT>
B. 检索上下文节点的孙节点

此 XPath 查询选定上下文节点的 <Customer> 子元素的所有 <Order> 子元素：

/child::Customer/child::Order

在此查询中，child 是轴，Customer 和 Order 是节点测试（如果 Customer 和 Order 是 <element> 节点，则这些节点测试为 TRUE，因为 <element> 节点是 child 轴的主要节点）。对于每个匹配 <Customer> 的节点，将匹配 <Orders> 的节点添加到结果中。结果集中只返回 <Order>。

child 是默认轴。因此，可将此查询指定为：

/Customer/Order

在映射架构上测试 XPath 查询

  1. 创建下面的模板 (MyTemplate.xml) 并将其保存在与 template 虚拟名称相关联的目录中。
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:xpath-query mapping-schema="SampleSchema1.xml">
    /Customer/Order
  </sql:xpath-query>
</ROOT>
  2. 下面的 URL 执行模板：
    http://IISServer/VirtualRoot/template/MyTemplate.xml

This XPath query can be specified directly in the URL:
http://IISServer/nwind/schema/SampleSchema1.xml/Customer/Order?root=root

    虚拟名称 schema 是 schema 类型。架构文件存储在与 schema 类型虚拟名称相关联的目录下。root 参数用于为所得到的 XML 文档指定顶层元素（root 可为任意值）。

    以下是模板执行的部分结果集：

    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <Order OrderID="Ord-10643" EmployeeID="6"
         OrderDate="1997-08-25T00:00:00"
         RequiredDate="1997-09-22T00:00:00"
         ShippedDate="1997-09-02T00:00:00">
    <OrderDetail ProductID="Prod-28" UnitPrice="45.6" Quantity="15">
      <Discount>0.25</Discount>
    </OrderDetail>
    <OrderDetail ProductID="Prod-39" UnitPrice="18" Quantity="21">
      <Discount>0.25</Discount>
    </OrderDetail>
    <OrderDetail ProductID="Prod-46" UnitPrice="12" Quantity="2">
      <Discount>0.25</Discount>
    </OrderDetail>
  </Order>
   ...
</ROOT>

如果将 XPath 查询指定为 Customer/Order/OrderDetail，则对于匹配 <Customer> 的每个节点，查询将浏览它们的 <Orders> 元素。而对于匹配 <Order> 的每个节点，查询将节点 <OrderDetail> 添加到结果中。结果集中只返回 <OrderDetail>。

C. 用 .. 指定父轴

此查询检索所有父元素是 CustomerID 特性值为 ALFKI 的 <Customer> 元素的 <Order> 元素。此查询在谓词中使用 parent 轴查找 <Order> 元素的父元素。

/child::Customer/child::Order[../@CustomerID="ALFKI"]

child 是默认轴。因此，查询可以指定为：

/Customer/Order[../@CustomerID="ALFKI"]

此 XPath 查询等同于：

/Customer[@CustomerID="ALFKI"]/Order.

说明 XPath 查询 /Order[../@CustomerID="ALFKI"] 将返回一个错误，因为 Order 没有父元素。虽然在包含 Order 的映射架构中可能有元素，但是该 XPath 并不是以它们中的任何一个开始；因此，Order 被视为该文档中的顶层元素类型。

在映射架构上测试 XPath 查询

  1. 创建下面的模板 (MyTemplate.xml) 并将其保存在与 template 虚拟名称相关联的目录中：
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:xpath-query mapping-schema="SampleSchema1.xml">
    /Customer/Order[../@CustomerID="ALFKI"]
  </sql:xpath-query>
</ROOT>
  2. 下面的 URL 执行模板：
    http://IISServer/VirtualRoot/template/MyTemplate.xml
  3. 以下是模板执行的部分结果集：
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
<Order OrderID="Ord-10643" EmployeeID="6"
          OrderDate="1997-08-25T00:00:00"
          RequiredDate="1997-09-22T00:00:00"
          ShippedDate="1997-09-02T00:00:00">
  <OrderDetail ProductID="Prod-28" UnitPrice="45.6" Quantity="15">
    <Discount>0.25</Discount>
  </OrderDetail>
  <OrderDetail ProductID="Prod-39" UnitPrice="18" Quantity="21">
    <Discount>0.25</Discount>
  </OrderDetail>
  <OrderDetail ProductID="Prod-46" UnitPrice="12" Quantity="2">
    <Discount>0.25</Discount>
  </OrderDetail>
   ...
</Order>
</ROOT>
D. 指定特性轴

此 XPath 查询选定 CustomerID 特性值为 ALFKI 的上下文节点的所有 <Customer> 子元素：

/child::Customer[attribute::CustomerID="ALFKI"]

在谓词 attribute::CustomerID 中，attribute 是轴，CustomerID 是节点测试（如果 CustomerID 是特性，则该节点测试为 TRUE，因为 <attribute> 节点是 attribute 轴的主要节点）。

可以指定 attribute 轴 (@) 的快捷方式，而且因为 child 是默认轴，所以可以在查询中省略它：

/Customer[@CustomerID="ALFKI"]

在映射架构上测试 XPath 查询

  1. 创建下面的模板 (MyTemplate.xml) 并将其保存在与 template 虚拟名称相关联的目录中：
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:xpath-query mapping-schema="SampleSchema1.xml">
    child::Customer[attribute::CustomerID="ALFKI"]
  </sql:xpath-query>
</ROOT>
  2. 下面的 URL 执行模板：
    http://IISServer/VirtualRoot/template/MyTemplate.xml

    可直接在 URL 中指定该 XPath 查询：

    http://IISServer/nwind/schema/SampleSchema1.xml/Customer[@CustomerID="ALFKI"]?root=root

    虚拟名称 schema 是 schema 类型。架构文件存储在与 schema 类型虚拟名称相关联的目录下。root 参数用于为所得到的 XML 文档指定顶层元素（root 可为任意值）。

    以下是模板执行的部分结果集：

    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <Customer CustomerID="ALFKI" CompanyName="Alfreds Futterkiste"
                 ContactName="Maria Anders" PostalCode="12209"
                 Country="Germany" Phone="030-0074321" Fax="030-0076545"
                 Orders="Ord-10643 Ord-10692 Ord-10702 Ord-10835 Ord-10952
                         Ord-11011">
    <Order OrderID="Ord-10643" EmployeeID="6"
               OrderDate="1997-08-25T00:00:00"
               RequiredDate="1997-09-22T00:00:00"
               ShippedDate="1997-09-02T00:00:00">
         <OrderDetail ProductID="Prod-28" UnitPrice="45.6" Quantity="15">
              <Discount>0.25</Discount>
          </OrderDetail>
         <OrderDetail ProductID="Prod-39" UnitPrice="18" Quantity="21">
              <Discount>0.25</Discount>
          </OrderDetail>
         <OrderDetail ProductID="Prod-46" UnitPrice="12" Quantity="2">
              <Discount>0.25</Discount>
          </OrderDetail>
  </Order>
   ...
</ROOT>


在 XPath 查询中指定布尔值谓词

以下示例显示如何在 XPath 查询中指定布尔值谓词。这些示例中的 XPath 查询都是在 SampleSchema1.xml 中所包含的映射架构上指定。有关此示例架构的信息，请参见示例 XPath 查询。

示例
A. 指定多个谓词

下面的 XPath 查询使用多个谓词查找给定订单 ID 和客户 ID 的订单信息：

/child::Customer[attribute::CustomerID="ALFKI"]/child::Order[attribute::OrderID="Ord-10643"]

可以指定 attribute 轴 (@) 的快捷方式，而且因为 child 是默认轴，所以可以在查询中省略它：

/Customer[@CustomerID="ALFKI"]/Order[@OrderID="Ord-10643"]

在映射架构上测试 XPath 查询

  1. 创建下面的模板 (MyTemplate.xml) 并将其保存在与 template 虚拟名称相关联的目录中：
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:xpath-query mapping-schema="SampleSchema1.xml">
    /Customer[@CustomerID="ALFKI"]/Order[@OrderID="Ord-10643"]
  </sql:xpath-query>
</ROOT>
  2. 下面的 URL 执行模板：
    http://IISServer/VirtualRoot/template/MyTemplate.xml

    可直接在 URL 中指定此 XPath 查询：

    http://IISServer/nwind/schema/SampleSchema1.xml/Customer[@CustomerID="ALFKI"]/Order[@OrderID="Ord-10643"]?root=root

    虚拟名称 schema 是 schema 类型。架构文件存储在与 schema 类型虚拟名称相关联的目录下。root 参数用于为所得到的 XML 文档指定顶层元素（root 可为任意值）。

    下面是部分结果：

    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <Order OrderID="Ord-10643" EmployeeID="6"
             OrderDate="1997-08-25T00:00:00"
             RequiredDate="1997-09-22T00:00:00"
             ShippedDate="1997-09-02T00:00:00">
  <OrderDetail ProductID="Prod-28" UnitPrice="45.6" Quantity="15">
    <Discount>0.25</Discount>
  </OrderDetail>
  <OrderDetail ProductID="Prod-39" UnitPrice="18" Quantity="21">
    <Discount>0.25</Discount>
  </OrderDetail>
  <OrderDetail ProductID="Prod-46" UnitPrice="12" Quantity="2">
    <Discount>0.25</Discount>
  </OrderDetail>
  </Order>
</ROOT>
B. 指定连续谓词和嵌套谓词

此查询显示如何使用连续谓词。此查询返回包含 City 特性的上下文节点的所有 <Customer> 子元素，而该 City 特性同时具有 London 和 Fax 特性的值：

/child::Customer[attribute::City="London"][attribute::Fax]

此查询返回同时满足谓词所指定的两个条件的 <Customer> 元素。

可以指定 attribute 轴 (@) 的快捷方式，而且因为 child 是默认轴，所以可以在查询中省略它：

/Customer[@City="London"][@Fax]

下面的 XPath 查询说明嵌套谓词的使用。该查询返回包含 <Order> 子元素的上下文节点的所有 <Customer> 子元素，而该 <Order> 子元素的至少一个 <Order> 元素的 EmployeeID 特性值为 2。

/Customer[Order[@EmployeeID=2]]

在映射架构上测试 XPath 查询

  1. 创建下面的模板 (MyTemplate.xml) 并将其保存在与 template 虚拟名称相关联的目录中：
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:xpath-query mapping-schema="SampleSchema1.xml">
         /Customer[@City="London"][@Fax]
  </sql:xpath-query>
</ROOT>
  2. 下面的 URL 执行模板：
    http://IISServer/VirtualRoot/template/MyTemplate.xml

This XPath query can be specified directly in the URL:
http://IISServer/nwind/schema/SampleSchema1.xml/Customer[@City="London"][@Fax]?root=root

    虚拟名称 schema 是 schema 类型。架构文件存储在与 schema 类型虚拟名称相关联的目录下。root 参数用于为所得到的 XML 文档指定顶层元素（root 可为任意值）。

C. 指定顶层谓词

此查询返回包含 <Order> 子元素的上下文节点的 <Customer> 子元素节点。此查询将位置路径作为顶层谓词进行测试：

/child::Customer[child::Order]

child 是默认轴。因此，可将该查询指定为：

/Customer[Order]

在映射架构上测试 XPath 查询

  1. 创建下面的模板 (MyTemplate.xml) 并将其保存在与 template 虚拟名称相关联的目录中。
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:xpath-query mapping-schema="SampleSchema1.xml">
    /Customer[Order]
  </sql:xpath-query>
</ROOT>
  2. 下面的 URL 执行模板：
    http://IISServer/VirtualRoot/template/MyTemplate.xml

    可直接在 URL 中指定此 XPath 查询：

    http://IISserver/nwind/schema/SampleSchema1.xml/Customer[Order]?root=root

    虚拟名称 schema 是 schema 类型。架构文件存储在与 schema 类型虚拟名称相关联的目录下。root 参数用于为所得到的 XML 文档指定顶层元素（root 可为任意值）。

    下面是部分结果：

    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <Customer CustomerID="ALFKI" CompanyName="Alfreds Futterkiste"
         ContactName="Maria Anders" PostalCode="12209" Country="Germany"
         Phone="030-0074321" Fax="030-0076545" Orders="Ord-10643 Ord-10692
                     Ord-10702 Ord-10835 Ord-10952 Ord-11011">
    <Order OrderID="Ord-10643" EmployeeID="6"
             OrderDate="1997-08-25T00:00:00"
             RequiredDate="1997-09-22T00:00:00"
             ShippedDate="1997-09-02T00:00:00">
          <OrderDetail ProductID="Prod-28" UnitPrice="45.6" Quantity="15">
              <Discount>0.25</Discount>
            </OrderDetail>
          <OrderDetail ProductID="Prod-39" UnitPrice="18" Quantity="21">
              <Discount>0.25</Discount>
           </OrderDetail>
          <OrderDetail ProductID="Prod-46" UnitPrice="12" Quantity="2">
              <Discount>0.25</Discount>
           </OrderDetail>
    </Order>
     ...
  <Customer>
  ...
<ROOT>


在 XPath 查询中指定关系运算符

以下示例显示如何在 XPath 查询中指定关系运算符。这些示例中的 XPath 查询都是在 SampleSchema1.xml 中所包含的映射架构上指定。有关此示例架构的信息，请参见示例 XPath 查询。

示例
A. 指定关系运算符

下面的 XPath 查询返回 <Customer> 元素，该元素的至少一个 <Order> 子元素包含 Quantity 特性值大于 5 的 <OrderDetail> 子元素：

/child::Customer[Order/OrderDetail[@Quantity>5]]

括号内指定的谓词筛选 <Customer> 元素。只返回至少一个 <OrderDetail> 孙元素的 Quantity 特性值大于 5 的 <Customer> 元素。

child 是默认轴。 因此，可将该查询指定为：

/Customer[Order/OrderDetail[@Quantity>5]]

在映射架构上测试 XPath 查询

  1. 创建下面的模板 (MyTemplate.xml) 并将其保存在与 template 虚拟名称相关联的目录中：
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:xpath-query mapping-schema="SampleSchema1.xml">
    /Customer[Order/OrderDetail[@Quantity>5]]
  </sql:xpath-query>
</ROOT>
  2. 下面的 URL 执行模板：
    http://IISServer/VirtualRoot/template/MyTemplate.xml

    可直接在 URL 中指定此 XPath 查询：

    http://IISServer/nwind/schema/SampleSchema1.xml/Customer[Order/OrderDetail[@Quantity>5]]?root=root

    虚拟名称 schema 是 schema 类型。架构文件存储在与 schema 类型虚拟名称相关联的目录下。root 参数用于为所得到的 XML 文档指定顶层元素（root 可为任意值）。

    以下是模板执行的部分结果集：

    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <Customer CustomerID="ALFKI" CompanyName="Alfreds Futterkiste"
         ContactName="Maria Anders" PostalCode="12209" Country="Germany"
        Phone="030-0074321" Fax="030-0076545"
          Orders="Ord-10643 Ord-10692 Ord-10702 Ord-10835 Ord-10952
                Ord-11011">
    <Order OrderID="Ord-10643" EmployeeID="6"
        OrderDate="1997-08-25T00:00:00"
        RequiredDate="1997-09-22T00:00:00"
        ShippedDate="1997-09-02T00:00:00">
      <OrderDetail ProductID="Prod-28" UnitPrice="45.6" Quantity="15">
              <Discount>0.25</Discount>
      </OrderDetail>
      <OrderDetail ProductID="Prod-39" UnitPrice="18" Quantity="21">
              <Discount>0.25</Discount>
      </OrderDetail>
      <OrderDetail ProductID="Prod-46" UnitPrice="12" Quantity="2">
              <Discount>0.25</Discount>
      </OrderDetail>
    </Order>
  </Customer>
   ...
</ROOT>
B. 在 XPath 查询内指定关系运算符并用布尔函数比较结果

该查询返回 EmployeeID 特性值小于 4 的上下文节点的所有 <Order> 子元素：

/child::Customer/child::Order[(attribute::EmployeeID < 4)=true()]

可以指定 attribute 轴 (@) 的快捷方式，而且因为 child 是默认轴，所以可以在查询中省略它：

/Customer/Order[(@EmployeeID < 4)=true()]

说明 在模板中指定该查询时，因为 < 字符在 XML 文档中有特殊含义，所以 < 字符必须是实体编码。在模板中，使用 &lt 指定 < 字符。

在映射架构上测试 XPath 查询

  1. 创建下面的模板 (MyTemplate.xml) 并将其保存在与 template 虚拟名称相关联的目录中：
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
    <sql:xpath-query mapping-schema="SampleSchema1.xml">
        /Customer/Order[(@EmployeeID&lt;4)=true()]
    </sql:xpath-query>
</ROOT>
  2. 下面的 URL 执行模板：
    http://IISServer/VirtualRoot/template/MyTemplate.xml


在 XPath 查询中指定算术运算符

以下示例显示如何在 XPath 查询中指定算术运算符。这些示例中的 XPath 查询都是在 SampleSchema1.xml 中所包含的映射架构上指定。有关此示例架构的信息，请参见示例 XPath 查询。

示例
A. 指定算术运算符 *

此 XPath 查询返回满足指定谓词的 <OrderDetail> 元素：

/child::OrderDetail[@UnitPrice * @Quantity = 98]

在此查询中，child 是轴，OrderDetail 是节点测试（如果 OrderDetail 是 <element node>，则该测试为 TRUE，因为 <element> 节点是 child 轴的主要节点）。对于所有 <OrderDetail> 元素节点，应用谓词中的测试，并且只返回满足条件的节点。

说明 XPath 中的数字是双精度浮点数，而在本例中比较浮点数将导致四舍五入。

在映射架构上测试 XPath 查询

  1. 创建下面的模板 (MyTemplate.xml) 并将其保存在与 template 虚拟名称相关联的目录中：
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:xpath-query mapping-schema="SampleSchema1.xml">
    /OrderDetail[@UnitPrice * @Quantity = 98]
  </sql:xpath-query>
</ROOT>
  2. 下面的 URL 执行模板：
    http://IISServer/VirtualRoot/template/MyTemplate.xml

    可直接在 URL 中指定此 XPath 查询：

    http://IISServer/nwind/schema/SampleSchema1.xml/OrderDetail[@UnitPrice*@Quantity=98]?root=root

    虚拟名称 schema 是 schema 类型。架构文件存储在与 schema 类型虚拟名称相关联的目录下。root 参数用于为所得到的 XML 文档指定顶层元素（root 可为任意值）。因为加号 (+) 在 URL 中有特殊的含义，当直接在 URL 中指定 XPath 查询时，不能使用算术运算符。在模板中指定查询时不会发生这个问题。

    以下是模板执行的部分结果集：

    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <OrderDetail ProductID="Prod-33" UnitPrice="2" Quantity="49">
    <Discount>0</Discount>
  </OrderDetail>
  <OrderDetail ProductID="Prod-42" UnitPrice="9.8" Quantity="10">
    <Discount>0</Discount>
  </OrderDetail>
  <OrderDetail ProductID="Prod-52" UnitPrice="7" Quantity="14">
    <Discount>5.0000001E-2</Discount>
  </OrderDetail>
  <OrderDetail ProductID="Prod-67" UnitPrice="14" Quantity="7">
    <Discount>0</Discount>
  </OrderDetail>
   ...
</ROOT>


在 XPath 查询中指定显式转换

以下示例显示如何在 XPath 查询中指定显式转换函数。这些示例中的 XPath 查询都是在 SampleSchema1.xml 中所包含的映射架构上指定。有关此示例架构的信息，请参见示例 XPath 查询。

示例
A. 使用显式转换函数 number()

number() 函数将参数转换为数字。

假设 EmployeeID 的值是非数字的，以下查询将 EmployeeID 转换为数字，并将其与 4 比较。该查询返回 EmployeeID 特性的数值为 4 的上下文节点的所有 <Employee> 子元素：

/child::Employee[number(attribute::EmployeeID)=4]

可以指定 attribute 轴 (@) 的快捷方式，而且因为 child 是默认轴，所以可以在查询中省略它：

/Employee[number(@EmployeeID)=4]

在关系术语中，该查询返回 EmployeeID 为 4 的职员。

在映射架构上测试 XPath 查询

  1. 创建下面的模板 (MyTemplate.xml) 并将其保存在与 template 虚拟名称相关联的目录中：
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:xpath-query mapping-schema="SampleSchema1.xml">
    /Employee[number(@EmployeeID)=4]
  </sql:xpath-query>
</ROOT>
  2. 下面的 URL 执行模板：
    http://IISServer/VirtualRoot/template/MyTemplate.xml
B. 使用显式转换函数 string()

string() 函数将参数转换为字符串。

以下查询将 EmployeeID 转换为字符串，并将其与值 4 比较。该查询返回 EmployeeID 特性的字符串值为 4 的上下文节点的所有 <Employee> 子元素：

/child::Employee[string(attribute::EmployeeID)="4"]

可以指定 attribute 轴 (@) 的快捷方式，而且因为 child 是默认轴，所以可以在查询中省略它：

/Employee[string(@EmployeeID)="4"]

在关系术语中，该查询返回 EmployeeID 为 4 的职员。

以下查询返回 ContactName 特性为空白字符串的 <Customer> 元素：

Customer[string(@ContactName)=true()]

在映射架构上测试 XPath 查询

  1. 创建下面的模板 (MyTemplate.xml) 并将其保存在与 template 虚拟名称相关联的目录中。
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:xpath-query mapping-schema="SampleSchema1.xml">
    Employee[string(@EmployeeID)="4"]
  </sql:xpath-query>
</ROOT>
  2. 下面的 URL 执行模板：
    http://IISServer/VirtualRoot/template/MyTemplate.xml


在 XPath 查询中指定布尔运算符

以下示例显示如何在 XPath 查询中指定布尔运算符。这些示例中的 XPath 查询都是在 SampleSchema1.xml 中所包含的映射架构上指定。有关此示例架构的信息，请参见示例 XPath 查询。

示例
A. 指定 OR 布尔运算符

该 XPath 查询返回 CustomerID 特性值为 ALFKI 或 ANATR 的上下文节点的 <Customer> 子元素：

/child::Customer[attribute::CustomerID="ALFKI" or attribute::CustomerID="ANATR"]

可以指定 attribute 轴 (@) 的快捷方式，而且因为 child 是默认轴，所以可以在查询中省略它：

/Customer[@CustomerID="ALFKI" or @CustomerID="ANATR"]

在该谓词中，attribute 是轴，CustomerID 是节点测试（如果 CustomerID 是 <attribute> 节点，则该测试为 TRUE，因为 <attribute> 节点是 attribute 轴的主要节点）。该谓词对 <Customer> 元素进行筛选，只返回那些满足谓词指定条件的元素。

在映射架构上测试 XPath 查询

  1. 创建下面的模板 (MyTemplate.xml) 并将其保存在与 template 虚拟名称相关联的目录中：
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:xpath-query mapping-schema="SampleSchema1.xml">
    /Customer[@CustomerID="ALFKI" or @CustomerID="ANATR"]
  </sql:xpath-query>
</ROOT>
  2. 下面的 URL 执行模板：
    http://IISServer/VirtualRoot/template/MyTemplate.xml

    可直接在 URL 中指定此 XPath 查询：

    http://IISServer/nwind/schema/SampleSchema1.xml/Customer[@CustomerID="ALFKI" or @CustomerID="ANATR"]?root=root

    虚拟名称 schema 是 schema 类型。架构文件存储在与 schema 类型虚拟名称相关联的目录下。root 参数用于为所得到的 XML 文档指定顶层元素（root 可为任何值）。


在 XPath 查询中指定布尔函数

以下示例显示如何在 XPath 查询中指定布尔函数。这些示例中的 XPath 查询都是在 SampleSchema1.xml 中所包含的映射架构上指定。有关此示例架构的信息，请参见示例 XPath 查询。

示例
A. 指定布尔函数 not()

该查询返回不含 <Order> 子元素的上下文节点的所有 <Customer> 子元素：

/child::Customer[not(child::Order)]

child 是默认轴。因此，可将该查询指定为：

/Customer[not(Order)]

在映射架构上测试 XPath 查询

  1. 创建下面的模板 (MyTemplate.xml) 并将其保存在与 template 虚拟名称相关联的目录中：
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:xpath-query mapping-schema="SampleSchema1.xml">
    Customer[not(Order)]
</sql:xpath-query>
</ROOT>
  2. 下面的 URL 执行模板：
    http://IISServer/VirtualRoot/template/MyTemplate.xml

    可直接在 URL 中指定此 XPath 查询：

    http://IISServer/nwind/schema/SampleSchema1.xml/Customer[not(Order)]?root=root

    虚拟名称 schema 是 schema 类型。架构文件存储在与 schema 类型虚拟名称相关联的目录下。root 参数用于为所得到的 XML 文档指定顶层元素（root 可为任意值）。

    下面是结果：

     <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
    <Customer CustomerID="FISSA"
              CompanyName="FISSA Fabrica Inter. Salchichas S.A."
                  ContactName="Diego Roel"
              PostalCode="28034" Country="Spain"
                  Phone="(91) 555 94 44" Fax="(91) 555 55 93" />
    <Customer CustomerID="PARIS"
              CompanyName="Paris spécialités"
                  ContactName="Marie Bertrand"
              PostalCode="75012" Country="France"
                   Phone="(1) 42.34.22.66" Fax="(1) 42.34.22.77" />
  </ROOT>
B. 指定布尔函数 true() 和 false()

此查询返回不含 <Order> 子元素的上下文节点的所有 <Customer> 子元素。在关系术语中，此查询返回所有没下任何订单的客户。

/child::Customer[child::Order=false()]

child 是默认轴。因此，可将该查询指定为：

/Customer[Order=false()]

此查询等同于：

/Customer[not(Order)]

此查询返回所有至少下了一份订单的客户：

/Customer[Order=true()]

此查询等同于：

/Customer[Order]

在映射架构上测试 XPath 查询

  1. 创建下面的模板 (MyTemplate.xml) 并将其保存在与 template 虚拟名称相关联的目录中：
    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:xpath-query mapping-schema="SampleSchema1.xml">
    /Customer[Order=false()]
  </sql:xpath-query>
</ROOT>
  2. 下面的 URL 执行模板：
    http://IISServer/VirtualRoot/template/MyTemplate.xml


在 XPath 查询中指定 XPath 变量

以下示例显示如何在 XPath 查询内传递 XPath 变量。这些示例中的 XPath 查询都是在 SampleSchema1.xml 中所包含的映射架构上指定。有关此示例架构的信息，请参见示例 XPath 查询。

示例
A. 使用 XPath 变量

一个示例模板包括两个 XPath 查询。每个 XPath 查询带有一个参数。模板也为这些参数指定默认值。如果未指定参数值，将使用默认值。在 <sql:header> 中指定了两个带默认值的参数。

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:header>
     <sql:param name='CustomerID'>ALFKI</sql:param>
     <sql:param name='EmployeeID'>1</sql:param>
  </sql:header>
  <sql:xpath-query mapping-schema="SampleSchema1.xml">
    Customer[@CustomerID=$CustomerID]
  </sql:xpath-query >
  <sql:xpath-query mapping-schema="SampleSchema1.xml">
   Employee[@EmployeeID=$EmployeeID]
  </sql:xpath-query>
</ROOT>

该模板存储在文件 (MyTemplate.xml) 中，并用 URL 执行：

http://IISServer/VirtualRoot/template/MyTemplate.xml

在此 URL 中不传递参数。因此，使用默认参数值。

在下列 URL 中，提供了 CustomerID 参数值。因此，将忽略默认客户 ID 值 ALFKI。由于未提供 EmployeeID 参数值，所以使用默认值。

http://IISServer/VirtualRoot/template/MyTemplate.xml?CustomerID=BERGS

在以下 URL 中，传递两个参数值（忽略默认值）。

http://IISServer/VirtualRoot/template/MyTemplate.xml?CustomerID=BERGS&EmployeeID=2

说明 可直接在 URL 中指定此 XPath 查询： http://IISServer/nwind/schema/SampleSchema1.xml/Customer[@CustomerID=$CustomerID]?CustomerID=ANATR&root=root。

虚拟名称 schema 是 schema 类型。架构文件存储在与 schema 类型虚拟名称相关联的目录下。root 参数用于为所得到的 XML 文档指定顶层元素（root 可为任意值）。


XPath 数据类型

Microsoft® SQL Server™ 2000、Xpath 和 XDR（简化 XML-Data）的数据类型有很大不同。例如，Xpath 没有整型和日期数据类型，而 SQL Server 和 XDR 却有很多数据类型。XDR 的时间值精度为十亿分之一秒，而 SQL Server 的时间值精度不超过 1/300 秒。因此，并不是总能将一种数据类型映射到另一种。有关将 SQL Server 数据类型映射到 XDR 数据类型的更多信息，请参见数据类型强制。

XPath 有三种数据类型：string、number 和 boolean。number 数据类型始终是 IEEE 754 双精度浮点数据。SQL Server float(53) 是与 XPath number 最接近的数据类型。但是，float(53) 并不完全是 IEEE 754。例如，float(53) 既不采用 NaN（非数据），也不采用无穷大。如果尝试将非数字字符串转换为 number 并试图用零去除，将导致错误。

XPath 转换

当使用 XPath 查询（如 OrderDetail[@UnitPrice > "10.0"]），隐性和显式数据类型转换会以微妙的方式更改查询的含义。因此，了解如何实现 XPath 数据类型很重要。可在 W3C Web 站点 http://www.w3.org/TR/1999/PR-xpath-19991008.html 中查找 XPath 语言规范、XML Path 语言 (XPath) 1.0 版（W3C 于1999 年 10 月 8 日提出）。

XPath 运算符分为四类：

  • 布尔运算符（and、or）

  • 关系运算符（<、>、<=、>=）

  • 等价运算符（=、!=）

  • 算术运算符（+、-、*、div、mod）

每类运算符转换其操作数的方式不同。XPath 运算符必要时隐性转换它们的操作数。算术运算符将操作数转换成 number 并生成数值。逻辑运算符将操作数转换成 boolean 并生成布尔值。关系运算符和等价运算符生成布尔值。但是，根据操作数的原始数据类型，它们有不同的转换规则，如下表所示。

操作数 | 关系运算符 | 等价运算符
两个操作数都是节点集 | 当且仅当一个节点集中有节点，另一个节点集中也有节点，这样它们的 string 值比较为 TRUE 时，为 TRUE。 | 相同
一个是节点集，一个是 string | 当且仅当节点集中有节点，这样当转换为 number 时，与转换为 number 的 string 的比较为 TRUE 时，为 TRUE。 | 当且仅当节点集中有节点，这样当转换为 string 时，与 string 的比较为 TRUE 时，为 TRUE。
一个是节点集，一个是 number | 当且仅当节点集中有节点，这样当转换为 number 时，与 number 的比较为 TRUE 时，为 TRUE。 | 相同
一个是节点集，一个是 boolean | 当且仅当节点集中有节点，这样当转换为 boolean，然后转换为 number 时，与转换为 number 的 boolean 的比较为 TRUE 时，为 TRUE。 | 当且仅当节点集中有节点，这样当转换为 boolean 时，与 boolean 的比较为 TRUE 时，为 TRUE。
两个都不是节点集 | 将两个操作数转换为 number，然后进行比较。 | 将两个操作数都转换为常用类型，然后进行比较。如果是 boolean、number 或 number，转换为 boolean，否则转换为 string。

说明 因为 XPath 关系运算符始终将操作数转换为 number，所以不可能进行 string 比较。为了包括日期比较，SQL Server 2000 在 XPath 规范的基础上做了如下改动：当关系运算符将 string 与 string 比较，将节点集与 string 比较，或将两个字符串值节点集互相比较时，执行 string 比较（而不是 number 比较）。

节点集转换

节点集转换有时不是直观的。节点集到 string 的转换通过只取节点集中第一个节点的字符串值来完成。节点集到 number 的转换通过先转换为 string，然后将 string 转换为 number 来完成。节点集到 boolean 的转换则是通过测试节点集是否存在来完成。

说明 因为 SQL Server 2000 不在节点集上进行位置选择（例如，XPath 查询 Customer[3] 表示第三个客户。 SQL Server 2000 不支持这种类型的位置选择。），所以不实现 XPath 规范所描述的节点集到 string 或节点集到 number 的转换。在 XPath 规范指定"first"语义的位置，SQL Server 2000 都使用"any"语义。例如，根据 W3C XPath 规范，此 XPath 查询 Order[OrderDetail/@UnitPrice > 10.0] 选择包含 UnitPrice 大于 10.0 的第一个 OrderDetail 的订单。在 SQL Server 2000 中，此 XPath 查询则选择包含 UnitPrice 大于 10.0 的任何 OrderDetail 的订单。

到 boolean 的转换将产生存在测试；因此，XPath 查询 Products[@Discontinued=true()] 等价于 SQL 表达式"Products.Discontinued is not null"，而不等价于 SQL 表达式"Products.Discontinued = 1"。若要获得第二个含义，首先将节点集转换成非 boolean 类型，如 number。例如，Products[number(@Discontinued) = true()]。

如果大多数运算符对于节点集中的任何或某个节点而言为 TRUE，则它们将被定义为 TRUE，所以如果节点集为空，则始终将这些运算符取值为 FALSE。因而，如果 A 为空，则 A = B 和 A != B 都为 FALSE，而 not(A=B) 和 not(A!=B) 都为 TRUE。

如果某列在数据库中不为空，则通常存在映射到该列的特性或元素。如果行有任何子元素，则存在映射到该行的元素。有关更多信息，请参见使用 sql:relation 和使用 sql:field。

说明 始终存在用 is-constant 批注的元素。因此，不能将 XPath 谓词用于 is-constant 元素。有关更多信息，请参见使用 sql:is-constant 创建常量元素。

将节点集转换为 string 或 number 时，将在带批注的架构中检查它的 XDR 类型（如果有）并用该类型确定所需的转换。

将 XDR 数据类型映射到 XPath 数据类型

节点的 XPath 数据类型源自架构中的 XDR 数据类型，如下表所示（EmployeeID 节点仅为说明之用）。

XDR 数据类型 | 等价 XPath 数据类型 | 所用的 SQL Server 转换
无 bin.base64 bin.hex | 暂缺 | 无 EmployeeID
boolean | 布尔型 | CONVERT(bit, EmployeeID)
number、int、float i1、i2、i4、i8 r4、r8 ui1、ui2、ui4、ui8 | 数字 | CONVERT(float(53), EmployeeID)
id、idref、idrefs entity、entities enumeration notation nmtoken、nmtokens char dateTime dateTime.tz string uri uuid | 字符串 | CONVERT(nvarchar(4000), EmployeeID, 126)
fixed14.4 | 暂缺（XPath 中没有等价于 fixed14.4 XDR 的数据类型） | CONVERT(money, EmployeeID)
date | 字符串 | LEFT(CONVERT(nvarchar(4000), EmployeeID, 126), 10)
time time.tz | 字符串 | SUBSTRING(CONVERT(nvarchar(4000), EmployeeID, 126), 1 + CHARINDEX(N'T', CONVERT(nvarchar(4000), EmployeeID, 126)), 24)

无论是用 SQL Server datetime 数据类型还是用 string 数据类型将值存储在数据库中，都将进行日期与时间转换。注意 SQL Server datetime 数据类型不使用 timezone，并且它的精度小于 XML time 数据类型。若要包括 timezone 数据类型或附加精度，请用 string 类型将数据存储于 SQL Server 2000 中。

当节点从 XDR 数据类型转换为 XPath 数据类型时，有时需要进行额外的转换工作（从一种 XPath 数据类型转换为另一种 XPath 数据类型）。例如，考察下面的 Xpath 查询：

(@m + 3) = 4

如果 @m 是 fixed14.4 XDR 数据类型，可用以下转换完成从 XDR 数据类型到 XPath 数据类型的转换：

CONVERT(money, m)

在该转换中，节点 m 从 fixed14.4 转换为 money。但是，添加值 3 需要额外的转换工作：

CONVERT(float(CONVERT(money, m))

此 XPath 表达式取值为：

CONVERT(float(CONVERT(money, m)) + CONVERT(float(53), 3) = CONVERT(float(53), 3)

如下表所示，该转换与应用于其它 XPath 表达式（如字面值或复合表达式）的转换相同。

 | X 未知 | X 是字符串 | X 是数字 | X 是布尔值
string(X) | CONVERT (nvarchar (4000), X, 126) | - | CONVERT (nvarchar (4000), X, 126) | CASE WHEN X THEN N'true' ELSE N'false' END
number(X) | CONVERT (float(53), X) | CONVERT (float(53), X) | - | CASE WHEN X THEN 1 ELSE 0 END
boolean(X) | - | LEN(X) > 0 | X != 0 | -

示例
A. 在 XPath 查询中转换数据类型

在带批注的 XDR 架构上指定的下列 XPath 查询中，该查询选定 EmployeeID 特性值为 E-1 的所有 Employee 节点，此处"E-"是用 sql:id-prefix 批注指定的前缀。

Employee[@EmployeeID="E-1"]

查询中的谓词等价于下面的 SQL 表达式：

N'E-' + CONVERT(nvarchar(4000), Employees.EmployeeID, 126) = N'E-1'

因为 EmployeeID 是 XDR 架构的 id（idref、idrefs、nmtoken、nmtokens 等等）数据类型值之一，所以用前面介绍的转换规则将 EmployeeID 转换为 string XPath 数据类型。

CONVERT(nvarchar(4000), Employees.EmployeeID, 126)

将前缀"E-"添加到字符串中，然后将结果与 N'E-1' 进行比较。

B. 在 XPath 查询中执行几种数据类型转换

考察在带批注的 XDR 架构上指定的下列 XPath 查询：OrderDetail[@UnitPrice * @Quantity > 98]

此 XPath 查询返回满足谓词 @UnitPrice * @Quantity > 98 的所有 <OrderDetail> 元素。如果在带批注的架构中用 fixed14.4 数据类型批注 UnitPrice，则该谓词等价于下面的 SQL 表达式：

CONVERT(float(53), CONVERT(money, [Order Details].UnitPrice)) * CONVERT(float(53), [Order Details].Quantity) > CONVERT(float(53), 98)

在转换 XPath 查询中的值时，第一个转换将 XDR 数据类型转换为 XPath 数据类型。因为 UnitPrice 的 XDR 数据类型是 fixed14.4（如前表所述），所用的第一个转换是：

CONVERT(money, [Order Details].UnitPrice))

因为算术运算符将操作数转换为 number XPath 数据类型，所以应用第二个转换（从一种 XPath 数据类型转换为另一种 XPath 数据类型）将值转换为 float(53)（float(53) 是与 XPath number 接近的数据类型）：

CONVERT(float(53), CONVERT(money, [Order Details].UnitPrice))

假设 Quantity 特性没有 XDR 数据类型，只用一次转换就可将 Quantity 转换为 number XPath 数据类型：

CONVERT(float(53), [Order Details].Quantity)

同样，值 98 转换为 number XPath 数据类型：

CONVERT(float(53), 98)

说明 如果架构中使用的 XDR 数据类型与数据库中的基础 SQL Server 数据类型不兼容，或者如果执行了不可能实现的 XPath 数据类型转换，SQL Server 可能会返回一个错误。例如，如果用 id-prefix 批注对 EmployeeID 特性进行了批注，XPath Employee[@EmployeeID=1] 将生成错误信息，原因是 EmployeeID 有 id-prefix 批注而无法转换为 number。


检索和编写 XML 数据

可以执行 SQL 查询返回 XML 格式而不是标准行集的结果。可以直接或从存储过程中执行这些查询。若要直接检索结果，请使用 SELECT 语句的 FOR XML 子句，并在 FOR XML 子句中指定 XML 模式：RAW、AUTO 或 EXPLICIT。

例如，下面的 SELECT 语句从 Northwind 数据库的 Customers 和 Orders 表中检索信息。下面的查询在 FOR XML 子句中指定 AUTO 模式：

SELECT Customers.CustomerID, ContactName, CompanyName,
       Orders.CustomerID, OrderDate
FROM Customers, Orders
WHERE Customers.CustomerID = Orders.CustomerID
AND (Customers.CustomerID = N'ALFKI'
    OR Customers.CustomerID = N'XYZAA')
ORDER BY Customers.CustomerID
FOR XML AUTO

尽管可用 FOR XML 子句检索 XML 文档形式的数据，但也可用 Transact-SQL OPENXML 函数插入以 XML 文档形式表示的数据。OPENXML 是类似于表或视图的行集提供程序，用于提供内存中 XML 文档上的行集。OPENXML 通过提供 XML 文档内部表示法的行集视图，允许访问 XML 数据，就好象它是关系行集一样。行集中的记录可以存储在数据库表中。OPENXML 可以在 SELECT 和 SELECT INTO 语句中使用，在这些语句中可以指定源表或视图。

下例说明 OPENXML 在 INSERT 和 SELECT 语句中的用法。示例 XML 文档由 <Customers> 和 <Orders> 元素组成。首先，sp_xml_preparedocument 存储过程分析 XML 文档。分析后的文档是 XML 文档各节点（元素、特性、文本、注释等）的树型表示法。然后 OPENXML 引用这个经过分析的 XML 文档并提供该 XML 文档的全部或部分内容的行集视图。使用 OPENXML 的 INSERT 语句从而可将数据从这样的行集插入数据库表。可用几个 OPENXML 调用提供 XML 文档各部分的行集视图并对它们进行处理，例如，将它们插入不同的表中（该过程也称为"将 XML 拆分到表中"）。在下例中，一个 XML 文档被这样拆分：使用两个 INSERT 语句将 <Customers> 元素存储在 Customers 表中并将 <Orders> 元素存储在 Orders 表中。

下例还显示带有 OPENXML 的 SELECT 语句从 XML 文档检索 CustomerID 和 OrderDate。

DECLARE @hDoc int
EXEC sp_xml_preparedocument @hDoc OUTPUT,
      N'<ROOT>
         <Customers CustomerID="XYZAA" ContactName="Joe"
               CompanyName="Company1">
            <Orders CustomerID="XYZAA"
               OrderDate="2000-08-25T00:00:00"/>
            <Orders CustomerID="XYZAA"
               OrderDate="2000-10-03T00:00:00"/>
         </Customers>
         <Customers CustomerID="XYZBB" ContactName="Steve"
               CompanyName="Company2">No Orders yet!
         </Customers>
      </ROOT>'
-- Use OPENXML to provide rowset consisting of customer data.
INSERT Customers
SELECT *
FROM OPENXML(@hDoc, N'/ROOT/Customers')
     WITH Customers
-- Use OPENXML to provide rowset consisting of order data.
INSERT Orders
SELECT *
FROM OPENXML(@hDoc, N'//Orders')
     WITH Orders
-- Using OPENXML in a SELECT statement.
SELECT * FROM OPENXML(@hDoc, N'/ROOT/Customers/Orders') with (CustomerID nchar(5) '../@CustomerID', OrderDate datetime)
-- Remove the internal representation of the XML document.
EXEC sp_xml_removedocument @hDoc

下例显示出前面由 sp_xml_pareparedocument 创建的 XML 文档经过分析的 XML 树状结构。

请参见

OPENXML

使用 OPENXML 编写 XML

使用 FOR XML 检索 XML 文档


使用 FOR XML 检索 XML 文档

可以对现有的关系数据库执行 SQL 查询，以返回 XML 文档形式而不是标准行集的结果。若要直接检索结果，请使用 SELECT 语句的 FOR XML 子句，并且在 FOR XML 子句中指定下列 XML 模式之一：

  • RAW

  • AUTO

  • EXPLICIT

这些模式仅在设置它们的查询执行时有效。它们对后面执行的任何查询的结果没有影响。除了指定 XML 模式外，还可以请求 XML-Data 架构。

请参见

使用 URL 执行模板文件

SELECT


FOR XML 子句的基本语法

在 FOR 子句中指定 XML 模式的基本语法为：

FOR XML mode [, XMLDATA] [, ELEMENTS][, BINARY BASE64]

参数

XML mode

指定 XML 模式。XML 模式决定所得到的 XML 的形式。
mode 可以是 RAW、AUTO 或 EXPLICIT。

XMLDATA

指定应返回 XML-Data 架构。文档的架构被预先设计为内嵌式架构。

ELEMENTS

如果指定 ELEMENTS 选项，则列作为子元素返回。否则，列将映射到 XML 特性。只有在 AUTO 模式下才支持该选项。

BINARY BASE64

如果指定 BINARY Base64 选项，则查询所返回的任何二进制数据都用 base64 编码格式表示。使用 RAW 和 EXPLICIT 模式检索二进制数据时，必须指定该选项。在 AUTO 模式中，默认情况下将二进制数据作为引用返回。

请参见

SELECT


FOR XML 子句的使用准则

FOR XML 子句只有在 SELECT 语句中及受到以下限制时才有效：

  • 无论在 UPDATE、INSERT 或 DELETE 语句、嵌套 SELECT 语句还是其它语句（SELECT INTO、赋值语句）中，FOR XML 在子选择中都无效。例如，不支持下面示例中的子选择：

    示例 A

    SELECT *
FROM Table1
WHERE ......(SELECT * FROM Table2 FOR XML RAW)

    示例 B

    DECLARE @doc nchar(3000)
SET @doc = (SELECT * FROM Customers WHERE CustomerID = 'ALFKI' FOR XML RAW)
  • 对于与 COMPUTE BY 或 FOR BROWSE 子句一起使用的任何选择语句，FOR XML 都无效，例如：
    SELECT OrderID, UnitPrice
FROM [Order Details]
ORDER BY OrderID COMPUTE SUM(UnitPrice) BY OrderID
  • 当前不支持 GROUP BY 和聚合函数与 FOR XML AUTO 共同使用。例如：
    SELECT max(price), min(price), avg(price)
FROM titles
FOR XML AUTO
  • FOR XML 在用于视图定义或用于返回行集的用户定义函数的 SELECT 语句中无效。例如，不能使用下面的语句：
    CREATE VIEW AllOrders AS SELECT * FROM Orders FOR XML AUTO

    但是允许如下的语句：

    SELECT * FROM ViewName FOR XML AUTO are allowed.
  • FOR XML 无法用于需要在存储过程中进一步处理的选择语句。

  • FOR XML 不能与游标一起使用。

  • 一般情况下，FOR XML 无法不能不直接将结果输出到 Microsoft® SQL Server™ 2000 客户端的任何选择语句。

  • FOR XML 无法用于在 INSERT 语句中调用的存储过程。

  • 如果带 FOR XML 子句的 SELECT 语句在查询中指定一个由四部分组成的名称，则在本地计算机上执行查询时，在所得到的 XML 文档中将不返回这个服务器名称。但是，当在网络服务器上执行查询时，将返回这个由四部分组成的服务器名称。

    例如，对于下面的查询：

    SELECT TOP 1 LastName
FROM ServerName.Northwind.dbo.Employees
FOR XML AUTO

    当 ServerName 是本地服务器时，该查询返回：

    <Northwind.dbo.Employees LastName="Buchanan"/>

    当 ServerName 是网络服务器时，该查询返回：

    <ServerName.Northwind.dbo.Employees LastName="Buchanan"/>

    通过指定下列别名可避免上述现象：

    SELECT TOP 1 LastName
FROM ServerName.Northwind.dbo.Employees x
FOR XML AUTO

    该查询返回：

    <x ="Buchanan"/>
  • 在带 FOR XML AUTO 子句的 SELECT 语句中使用派生表可能不会产生希望的嵌套。

    当指定使用 FOR XML AUTO 模式的查询时，将实现 FOR BROWSE 模式。FOR XML AUTO 模式使用 FOR BROWSE 模式提供的信息确定结果集中的层次结构。

    例如，请看下面的查询。在该查询中创建了派生表 P。

    SELECT c.CompanyName,
       o.OrderID,
       o.OrderDate,
       p.ProductName,
       p.Quantity,
       p.UnitPrice,
       p.Total
FROM   Customers AS c
       JOIN
       Orders AS o
       ON
       c.CustomerID = o.CustomerID
       JOIN
       (
         SELECT od.OrderID,
                pr.ProductName,
                od.Quantity,
                od.UnitPrice,
                od.Quantity * od.UnitPrice AS total
         FROM   Products AS pr
                JOIN
                [Order Details] AS od
                ON
                pr.ProductID = od.ProductID
       ) AS p
       ON
       o.OrderID = p.OrderID
FOR XML AUTO

    下面是部分结果：

    <c CompanyName="Vins et alcools Chevalier">
  <o OrderID="10248" OrderDate="1996-07-04T00:00:00">
    <pr ProductName="Queso Cabrales">
        <od Quantity="12" UnitPrice="14.0000" total="168.0000"/>
    </pr>
    <pr ProductName="Singaporean Hokkien Fried Mee">
        <od Quantity="10" UnitPrice="9.8000" total="98.0000"/>
    </pr>
</c>

    在所得到的 XML 文档中缺少 <p> 元素，且返回 <pr> 和 <od> 元素。发生这种现象的原因是查询优化器在结果中消除 P 表，并返回包含 od 表和 pr 表的结果集。

    通过重新编写该查询可避免上述现象。例如，可重新编写该查询以创建一个视图并在 SELECT 语句中使用该视图：

    CREATE VIEW p AS
         SELECT od.OrderID,
                pr.ProductName,
                od.Quantity,
                od.UnitPrice,
                od.Quantity * od.UnitPrice AS total
         FROM   Products AS pr
                JOIN
                [Order Details] AS od
                ON
                pr.ProductID = od.ProductID

    然后编写 SELECT 语句：

    SELECT c.CompanyName,
       o.OrderID,
       o.OrderDate,
       p.ProductName,
       p.Quantity,
       p.UnitPrice,
       p.total
FROM   Customers AS c
       JOIN
       Orders AS o
       ON
       c.CustomerID = o.CustomerID
       JOIN
        p
       ON
       o.OrderID = p.OrderID
FOR XML AUTO

    下面是部分结果：

    <c CompanyName="Vins et alcools Chevalier">
  <o OrderID="10248" OrderDate="1996-07-04T00:00:00">
    <p ProductName="Queso Cabrales"
       Quantity="12"
       UnitPrice="14.0000"
       total="168.0000"/>
  </o>
</c>

另外，将包含在 XML 名称中无效的字符（如空格）的 SQL Server 名称转换为 XML 名称的方法是将无效字符转换为转义数字实体编码。

仅有两个非字母字符可以在 XML 名称的开始位置使用：冒号 (:) 和下划线 (_)。因为冒号 (:) 已经保留给命名空间，所以将下划线 (_) 选作转义符。编码的转义规则是：

  • 不是有效 XML 名称字符（根据 XML 1.0 规范）的任何 UCS-2 字符均转义为 _xHHHH_ 的形式，其中 HHHH 代表字符的四位十六进制 UCS-2 代码，以最高有效位排在最前面的顺序。例如，表名 Order Details 编码为 Order_x0020_Details。

  • 不符合 UCS-2 领域的字符（介于 U+00010000 和 U+0010FFFF 范围之间的附加 UCS-4 字符）均编码为 _xHHHHHHHH_，其中 HHHHHHHH 代表字符的八位十六进制 UCS-4 编码。

  • 下划线字符不需要进行转义，除非其后为字符 x。例如，表名 Order_Details 不进行编码。

  • 标识符中的冒号 (:) 字符不进行编码，以便 FOR XML 查询可以生成命名空间元素和特性名。例如，下列查询在名称中生成包含冒号的命名空间特性：
    SELECT 'namespace-urn' as 'xmlns:namespace',
         1 as 'namespace:a'
FOR XML RAW

    该查询产生下列结果：

    <row xmlns:namespace="namespace-urn" namespace:a="1"/>
  • 在 SELECT 查询中，将任何列投影到二进制大对象 (BLOB) 会使该列成为临时实体（丢失相关联的表名和列名）。这使 AUTO 模式查询产生错误，因为它不知道将该值放在 XML 层次结构的何处，例如：
    CREATE TABLE MyTable (Col1 int PRIMARY KEY, Col2 binary)
INSERT INTO MyTable VALUES (1, 0x7)

    因为投影到 BLOB，该查询产生一个错误信息：

    SELECT Col1,
         CAST(Col2 as image) as Col2
FROM MyTable
FOR XML AUTO

    如果删除投影，该查询将产生预期的结果：

    SELECT Col1,
         Col2
FROM MyTable
FOR XML AUTO

    结果如下：

    <Computed Col1="1" Col2="dbobject/Computed[@Col1='1']/@Col2"/>

请参见

使用 HTTP 执行 SQL 语句

使用 HTTP 执行模板文件

SELECT


使用 RAW 模式

RAW 模式将查询结果集中的每一行转换为带有类属标识符 row 的 XML 元素。非 NULL 的任何列值均被映射到 XML 元素的特性，该元素中的特性名与列名相同。

在查询中指定 BINARY Base64 选项，以返回 base64 编码格式的二进制数据。在 RAW 模式下，不指定 BINARY base64 选项而检索二进制数据将导致错误。

当请求 XML-Data 架构时，声明为命名空间的架构出现在数据的开头。在结果中，对每个顶层元素重复架构命名空间引用。

示例

可以使用 SQL 查询分析器执行下列示例中的查询。若要使用 HTTP 执行这些查询，请参见使用 HTTP 访问 SQL Server。

A. 使用 RAW 模式检索客户和订单信息

下面的查询返回客户和订单信息。在 FOR XML 子句中指定 RAW 模式。

SELECT Customers.CustomerID, Orders.OrderID, Orders.OrderDate
FROM Customers, Orders
WHERE Customers.CustomerID = Orders.CustomerID
ORDER BY Customers.CustomerID
FOR XML RAW

下面是部分结果：

<row CustomerID="ALFKI" OrderID="10643" OrderDate="1997-08-25T00:00:00"/>
<row CustomerID="ANATR" OrderID="10308" OrderDate="1996-09-18T00:00:00"/>
<row CustomerID="ANATR" OrderID="10625" OrderDate="1997-08-08T00:00:00"/>
<row CustomerID="AROUT" OrderID="10355" OrderDate="1996-11-15T00:00:00"/>

可以使用外部联接指定上面的查询在结果集中返回所有客户，无论这些客户是否有订单。

SELECT C.CustomerID, O.OrderID, O.OrderDate
FROM Customers C LEFT OUTER JOIN Orders O ON C.CustomerID = O.CustomerID
ORDER BY C.CustomerID
FOR XML RAW

下面是部分结果：

<row CustomerID="BONAP" OrderID="11076" OrderDate="1998-05-06T00:00:00"/>
<row CustomerID="FISSA"/>
<row CustomerID="PARIS"/>
<row CustomerID="RICSU" OrderID="11075" OrderDate="1998-05-06T00:00:00"/>
B. 指定请求 XML-Data 架构的 XMLDATA 选项

下面的查询返回描述文档结构的 XML-DATA 架构。

SELECT TOP 2 Customers.CustomerID, Orders.OrderID, Orders.OrderDate
FROM Customers, Orders
WHERE Customers.CustomerID = Orders.CustomerID
ORDER BY Customers.CustomerID
FOR XML RAW , XMLDATA

下面是部分结果：

<Schema name="Schema3" xmlns="urn:schemas-microsoft-com:xml-data"
     xmlns:dt="urn:schemas-microsoft-com:datatypes">
  <ElementType name="row" content="empty" model="closed">
    <AttributeType name="CustomerID" dt:type="string"/>
    <AttributeType name="OrderID" dt:type="i4"/>
    <AttributeType name="OrderDate" dt:type="dateTime"/>
    <attribute type="CustomerID"/><attribute type="OrderID"/>
    <attribute type="OrderDate"/>
  </ElementType>
</Schema>
<row xmlns="x-schema:#Schema3" CustomerID="ALFKI" OrderID="10643"
     OrderDate="1997-08-25T00:00:00"/>
<row xmlns="x-schema:#Schema3" CustomerID="ALFKI" OrderID="10692"
     OrderDate="1997-10-03T00:00:00"/>

说明 该 <Schema> 被声明为命名空间。在不同的 FOR XML 查询中请求多个 XML-Data 架构时，若要避免命名空间冲突，命名空间标识符（本例中为 Schema3）应随每个查询执行更改。命名空间标识符由 Schema 及其后的整数组成。

C. 检索二进制数据

下面的查询返回 Employees 表中的职员照片。照片是 Employees 表中的 image 列。在查询中指定 BINARY Base64 选项，以返回 base64 编码格式的二进制数据。

SELECT TOP 1 Photo
FROM Employees
WHERE EmployeeID=1
FOR XML RAW, BINARY BASE64

结果如下：

<row Photo="Binary data in base64 format"/>
D. 直接指定检索二进制数据的 URL

因为 RAW 模式不支持寻址 URL 形式的二进制数据，本例使用 DBOBJECT/TABLE[@PK1="v1"]/@COLUMN 语法直接创建 URL。这将返回一个对可以在后面的操作中使用的图像数据的引用。

SELECT TOP 1 EmployeeID,
   'dbobject/Employees[@EmployeeID='+CAST(EmployeeID as
            nvarchar(4000))+']/@Photo' Photo
FROM Employees
FOR XML RAW

结果如下：

<row EmployeeID="3"
     Photo="dbobject/Employees[@EmployeeID3]/@Photo"/>

请参见

SELECT


使用 AUTO 模式

AUTO 模式将查询结果作为嵌套 XML 元素返回。在 FROM 子句内，每个在 SELECT 子句中至少有一列被列出的表都表示为一个 XML 元素。SELECT 子句中列出的列映射到适当的元素特性。当指定了 ELEMENTS 选项后，表列映射到子元素而非特性。默认情况下，AUTO 模式将表列映射到 XML 特性。

表名或别名（若有）映射到 XML 元素名。如果在查询中指定了 ELEMENTS 选项，则列名或别名（若有）映射到特性名或不复杂的子元素名。

结果集中的层次结构（元素的嵌套）基于 SELECT 子句中指定的列所标识的表顺序；因此，SELECT 子句中指定列名的顺序很重要。

用 SELECT 子句列出列名的顺序对表进行标识和嵌套。左数第一个标识的表形成所得到的 XML 文档中的顶层元素。左数第二个表（由 SELECT 语句中的列标识）形成顶层元素内的子元素，依此类推。

如果 SELECT 子句列出的某列名所在的表已由 SELECT 子句以前指定的列标识，则将该列作为已创建元素的特性（如果指定了 ELEMENTS 选项，则作为子元素）添加，而不是在层次结构中打开新的一层（即为该表添加新的子元素）。

例如，执行下列查询：

SELECT Customers.CustomerID, Orders.OrderID, Customers.ContactName
FROM Customers, Orders
WHERE Customers.CustomerID = Orders.CustomerID
FOR XML AUTO

下面是部分结果：

<Customers CustomerID="ALFKI" ContactName="Maria Anders">
  <Orders OrderID="10643"/>
  <Orders OrderID="10692"/>
  <Orders OrderID="10702"/>
  <Orders OrderID="10835"/>
  <Orders OrderID="10952"/>
  <Orders OrderID="11011"/>
</Customers>

注意，在 SELECT 子句中，用 CustomerID 标识 Customers 表。因此，创建 <Customer> 元素并向其添加特性 CustomerID。接下来，用 OrderID 列名标识 Orders 表。将 <Orders> 元素作为 <Customers> 的子元素添加，并将 OrderID 特性添加到 <Orders> 元素中。现在，用 ContactName 列标识 Customers 表，该表已由 CustomerID 列标识。因此，不创建新元素。而是将 ContactName 特性添加到已创建的 <Customers> 元素中。

该查询指定 ELEMENT 选项。因此，返回一个 element-centric（以元素为中心的）文档。

SELECT Customers.CustomerID, Orders.OrderID, Customers.ContactName
FROM Customers, Orders
WHERE Customers.CustomerID = Orders.CustomerID
FOR XML AUTO, ELEMENTS

下面是部分结果：

<Customers>
  <CustomerID>ALFKI</CustomerID>
  <ContactName>Maria Anders</ContactName>
        <Orders><OrderID>10643</OrderID></Orders>
        <Orders><OrderID>10692</OrderID></Orders>
        <Orders><OrderID>10702</OrderID></Orders>
        <Orders><OrderID>10835</OrderID></Orders>
        <Orders><OrderID>10952</OrderID></Orders>
        <Orders><OrderID>11011</OrderID></Orders>
</Customers>

下面的查询返回职员和订单信息。再次在 FOR XML 子句中指定 AUTO 模式。

SELECT Employees.EmployeeID, LastName, FirstName,
       OrderID, OrderDate, Orders.EmployeeID
FROM Orders, Employees
WHERE Orders.EmployeeID = Employees.EmployeeID
ORDER BY Employees.EmployeeID
FOR XML AUTO

下面显示部分结果。表名作为输出中的 XML 元素标志出现。对于 EmployeeID 的每个值都有一个 <Employee> 元素。

<Employees EmployeeID="1" LastName="Davolio" FirstName="Nancy">
  <Orders OrderID="10258" OrderDate="1996-07-17T00:00:00" EmployeeID="1"/>
  <Orders OrderID="10270" OrderDate="1996-08-01T00:00:00" EmployeeID="1"/>
</Employees>
<Employees EmployeeID="2" LastName="Fuller" FirstName="Andrew">
  <Orders OrderID="10248" OrderDate="1996-07-04T00:00:00" EmployeeID="5"/>
  <Orders OrderID="10249" OrderDate="1996-07-05T00:00:00" EmployeeID="6"/>
</Employees>

因为在 SELECT 子句中先标识 Employees 表然后再标识 Orders 表，所以在所得到的包含 <Orders> 子元素的层次结构中，<Employees> 元素作为最外面的元素出现。

在此例中，通过比较每两个相邻行的 EmployeeID 值，在所得到的 XML 文档中创建 <Employees> 元素。这样做是因为 EmployeeID 是表的主键。如果 EmployeeID 没有标识为 Employees 表的主键，则为每两个相邻行比较在 SELECT 语句中指定的 Employees 表中的所有列值（EmployeeID、LastName 和 FirstName）。如果两个相邻行的任何值都不同，则在结果中添加一个新的 <Employees> 元素。

在比较这些列值时，如果要比较的任何列是 text、ntext 或 image 类型，则 FOR XML 假定值不同（即使它们可能相同，因为 Microsoft® SQL Server™ 2000 不支持比较大对象），并将选定的每一行的元素添加到结果中。

如果 SELECT 子句中的某列无法与 FROM 子句所标识的任何表相关联（在聚合列或计算列的情况下），当该列在列表中出现时，将被添加到 XML 文档的最深嵌套级。如果该列作为 SELECT 子句的第一列出现，将被添加到顶层元素。

如果在 SELECT 子句中指定 * 通配符，则用上述方法（根据查询引擎返回行的顺序）确定嵌套。

在 AUTO 模式下不支持 GROUP BY 和聚合函数。但是，对于使用嵌套 SELECT 检索信息的工作区，请参见下面的示例 C。

如果在查询中指定 BINARY base64 选项，则二进制数据以 base64 编码格式返回。默认情况下（如果未指定 BINARY base64 选项），AUTO 模式支持二进制数据的 URL 编码。也就是说，不返回二进制数据，而是返回一个引用（相对于执行查询所在的数据库虚拟根的 URL），该引用可在后面的操作中用于访问实际的二进制数据。查询必须提供足够的信息（如主键列）才能标识图像。

在对表/视图指定的查询中，如果指定了视图二进制列的别名，则以该二进制数据的 URL 编码格式返回别名。在后续操作中，别名没有意义，也不能用 URL 编码检索图像。因此，在使用 FOR XML AUTO 模式查询视图时不要使用别名。

例如，当使用带 TOP n 选项或 DISTINCT 选项的 SELECT 语句创建视图时，主键信息将丢失。因此，如果对视图指定查询，以使用 OPEN XML AUTO 模式检索二进制列，将返回一个错误。例如，如果创建以下视图：

CREATE VIEW MyView as SELECT TOP 2 * FROM Employees

因为 MyView 没有将 EmployeeID 作为主键，所以该查询将产生错误：

SELECT EmployeeID, Photo
FROM MyView
WHERE EmployeeID = 1
FOR XML AUTO

如果对 Employees 表指定上述查询，则得到如下结果：

SELECT EmployeeID, Photo
FROM Employees
WHERE EmployeeID = 1
FOR XML AUTO
示例

可以使用 SQL 查询分析器执行这些示例中的查询。若要使用 HTTP 执行这些查询，请参见使用 HTTP 访问 SQL Server。

A. 使用 AUTO 模式检索职员和订单信息

下面的查询返回职员和订单信息。在 FOR XML 子句中指定 AUTO 模式：

SELECT Employees.EmployeeID, LastName, FirstName,
       OrderID, OrderDate, Orders.EmployeeID
FROM Orders, Employees
WHERE Orders.EmployeeID = Employees.EmployeeID
ORDER BY Employees.EmployeeID
FOR XML AUTO

下面显示部分结果。表名作为输出中的 XML 元素标志出现。对于 EmployeeID 的每个值都有一个 <Employee> 元素。

<Employees EmployeeID="1" LastName="Davolio" FirstName="Nancy">
  <Orders OrderID="10258" OrderDate="1996-07-17T00:00:00" EmployeeID="1"/>
  <Orders OrderID="10270" OrderDate="1996-08-01T00:00:00" EmployeeID="1"/>
</Employees>
<Employees EmployeeID="2" LastName="Fuller" FirstName="Andrew">
  <Orders OrderID="10248" OrderDate="1996-07-04T00:00:00" EmployeeID="5"/>
  <Orders OrderID="10249" OrderDate="1996-07-05T00:00:00" EmployeeID="6"/>
</Employees>

如果采用在 SELECT 子句中，在 Employees 表列之前指定 Orders 表中的列的方法来指定上述查询，则生成的层次结构中的顶层元素是 <Orders> 元素，下一层是 <Employees> 元素。

SELECT OrderID, OrderDate, Orders.EmployeeID,
       Employees.EmployeeID, LastName, FirstName
FROM Orders, Employees
WHERE Orders.EmployeeID = Employees.EmployeeID
ORDER BY Employees.EmployeeID
FOR XML AUTO

下面是部分结果：

<Orders OrderID="10258" OrderDate="1996-07-17T00:00:00" EmployeeID="1">
  <Employees EmployeeID="1" LastName="Davolio" FirstName="Nancy"/>
</Orders>
<Orders OrderID="10270" OrderDate="1996-08-01T00:00:00" EmployeeID="1">
  <Employees EmployeeID="1" LastName="Davolio" FirstName="Nancy"/>
</Orders>

在下面的查询中，Orders 表是基于 SELECT 语句中所指定列的最左边的表。结果 <Orders> 元素被创建为顶层元素。在 SELECT 语句中的下一步指定 Employees 表中的列。因此，<Employees> 元素表现为嵌套在 <Orders> 元素中。最后，在 SELECT 语句中指定 Orders 表中的某列。但是因为 Orders 表已经在层次结构的顶层，所以该列被添加到此元素，并且不再创建元素。

SELECT OrderID, Orders.EmployeeID,
       Employees.EmployeeID, LastName, FirstName, OrderDate
FROM Orders, Employees
WHERE Orders.EmployeeID = Employees.EmployeeID
AND Employees.EmployeeID=1 or Employees.EmployeeID=2
ORDER BY Employees.EmployeeID
FOR XML AUTO

下面是部分结果：

<Orders OrderID="10258" EmployeeID="1" OrderDate="1996-07-17T00:00:00">
  <Employees EmployeeID="1" LastName="Davolio" FirstName="Nancy"/>
</Orders>
<Orders OrderID="10270" EmployeeID="1" OrderDate="1996-08-01T00:00:00">
  <Employees EmployeeID="1" LastName="Davolio" FirstName="Nancy"/>
</Orders>
B. 指定表名的别名

下面的查询返回客户和订单信息。别名用于表名。

SELECT C.CustomerID, O.OrderID, O.OrderDate
FROM Customers C LEFT OUTER JOIN Orders O ON C.CustomerID = O.CustomerID
ORDER BY C.CustomerID
FOR XML AUTO

下面显示部分结果集。元素名与为查询中使用的表指定的别名相同。

<C CustomerID="ALFKI">
   <O OrderID="10643" OrderDate="1997-08-25T00:00:00"/>
   <O OrderID="10692" OrderDate="1997-10-03T00:00:00"/>
</C>
<C CustomerID="ANATR">
   <O OrderID="10308" OrderDate="1996-09-18T00:00:00"/>
</C>

在嵌套查询中，如果在内部查询中指定别名，则根据优化程序处理查询的方式，可能将不保留别名。例如：

SELECT TOP 2 *
FROM (SELECT FirstName+' '+LastName as FullName FROM Employees) as EMP
FOR XML AUTO

查询产生下面的结果：

<Employees FullName="Nancy Davolio"/>
<Employees FullName="Andrew Fuller"/>

在此结果中，元素名是 <Employees> 而非 <EMP>。

C. 指定 GROUP BY 和聚合函数

当前不支持 GROUP BY 和聚合函数与 FOR XML AUTO 模式共同使用。以下查询使用嵌套查询方法查找客户所下的订单数。下面的查询返回客户信息，其中包括客户所下的订单数、订单信息和订单详情信息。

内部 SELECT 语句（使用 GROUP BY 和 COUNT() 函数）用客户信息和客户所下的订单数生成一个表。此内部表随后与指定了 FOR XML 模式的外部查询的 FROM 子句中的表联接起来。

SELECT Cust.CustomerID, ContactName, NoOfOrders,
       O.OrderID, O.CustomerID,
       OD.ProductID, OD.Quantity
FROM (SELECT C.CustomerID, C.ContactName, count(*) as NoOfOrders
      FROM Customers C left outer join
           Orders O ON C.CustomerID = O.CustomerID
         GROUP BY C.CustomerID, C.ContactName) Cust
         left outer join Orders O on Cust.CustomerID = O.CustomerID
         left outer join [Order Details] OD on O.OrderID = OD.OrderID
FOR XML AUTO

下面是部分结果：

<Cust CustomerID="ALFKI" ContactName="Maria Anders" NoOfOrders="6">
  <O OrderID="10643" CustomerID="ALFKI">
    <OD ProductID="28" Quantity="15"/>
    <OD ProductID="39" Quantity="21"/>
    <OD ProductID="46" Quantity="2"/>
  </O>
  <O OrderID="10692" CustomerID="ALFKI">
    <OD ProductID="63" Quantity="20"/>
  </O>
</Cust>
D. 在 AUTO 模式下指定计算列

下面的查询返回串联的职员姓名和职员已经拿到的订单的订单 ID。计算列被分配给当时的最内层。因而，串联的职员姓名作为 <Order> 元素的特性添加到结果中。

SELECT FirstName+' '+LastName as Name,
       Orders.OrderID
FROM Employees left outer join Orders on
     Employees.EmployeeID=Orders.EmployeeID
ORDER BY Name
FOR XML AUTO

下面是部分结果：

<Orders Name="Andrew Fuller" OrderID="10265"/>
<Orders Name="Andrew Fuller" OrderID="10277"/>

若要获得具有 Name 特性且包含订单子元素的 <Emp> 元素，应使用子选择重新编写此查询。内部选择用包含职员姓名的计算列创建临时 Emp 表。该表然后与 Orders 表联接以获得结果。

SELECT Emp.name, Orders.OrderID
FROM (SELECT FirstName+' '+LastName as Name,
      EmployeeID
         FROM Employees) Emp
         left outer join Orders on Emp.EmployeeID = Orders.EmployeeID
ORDER BY Emp.Name
FOR XML AUTO

下面是部分结果：

<Emp name="Andrew Fuller">
  <Orders OrderID="10265"/>
  <Orders OrderID="10277"/>
  <Orders OrderID="10280"/>
</Emp>
E. 返回二进制数据

下面的查询返回 Employees 表中的职员照片。Photo 是 Employees 表中的 image 列。默认情况下，AUTO 模式返回对二进制数据的引用（相对于执行查询所在的数据库虚拟根的 URL）。必须指定 EmployeeID 键特性才能标识图像。如本例中那样检索图像引用时，还必须在 SELECT 子句中指定表的主键以唯一标识行。

SELECT EmployeeID, Photo
FROM Employees
WHERE EmployeeID=1
FOR XML AUTO

结果如下：

<Employees EmployeeID="1" Photo="dbobject/Employees[@EmployeeID='1']/@Photo"/>

用 BINARY Base64 选项执行上述查询。查询以 base64 编码格式返回二进制数据。

SELECT Photo
FROM Employees
WHERE EmployeeID=1
FOR XML AUTO, BINARY Base64

结果如下：

<Employees Photo="Here you see the Picture in base64 format"/>

在使用 AUTO 模式检索二进制数据时，默认情况下（例如未指定 BINARY base 64 选项）返回引用（相对于执行查询所在的数据库虚拟根的 URL）而不是二进制数据。在不区分大小写的数据库中，如果查询中指定的表/列名与数据库中的表/列名不匹配，则查询执行；但是，引用中返回的大小写将不一致。例如：

SELECT TOP 2 PHOTO, EMPLOYEEID FROM EMPLOYEES FOR XML AUTO

结果如下：

<EMPLOYEES PHOTO="dbobject/EMPLOYEES[@EmployeeID='1']/@Photo"
           EMPLOYEEID="1"/>
<EMPLOYEES PHOTO="dbobject/EMPLOYEES[@EmployeeID='2']/@Photo"
           EMPLOYEEID="2"/>

这可能是个问题，尤其当两个模板从不区分大小写的数据库中的同一个表请求数据，但却使用具有不同大小写的查询时。若要避免这样的问题，建议查询中指定的表/列名大小写应与数据库中的表/列名大小写相匹配。

F. 了解编码

下例显示发生在结果中的各种编码。

  1. 创建下表：
    CREATE TABLE [Special Chars] (Col1 char(1) primary key, [Col#&2] varbinary(50))
  2. 将下列数据添加到表中：
    INSERT INTO [Special Chars] values ('&', 0x20)
INSERT INTO [Special Chars] values ('#', 0x20)
  3. 该查询返回表中的数据。指定 FOR XML AUTO 模式。二进制数据作为引用返回。
    SELECT * FROM [Special Chars] FOR XML AUTO

结果如下：

<Special_x0020_Chars
Col1="#"
Col_x0023__x0026_2="dbobject/Special_x0020_Chars[@Col1='#']/@Col_x0023__x0026_2"
/>
<Special_x0020_Chars
Col1="&amp;"
Col_x0023__x0026_2="dbobject/Special_x0020_Chars[@Col1='&amp;']/@Col_x0023__x0026_2"
/>

以下是在结果中对特殊字符进行编码的过程：

  • 在查询结果中，用相应的 Unicode 字符编码的十六进制值对返回的元素及特性名中的特殊 XML 和 URL 字符进行编码。在前面的结果中，元素名 <Special Chars> 作为 <Special_x0020_Chars> 返回。特性名 <Col#&2> 作为 <Col_x0023__x0026_2> 返回（对 XML 和 URL 两种特殊字符都进行编码）。

  • 如果元素或特性的值包含 5 个标准 XML 字符实体（'、""、<、> 及 &）中的任何一个，就始终用 XML 字符编码对这些特殊 XML 字符进行编码。在上面的结果中，特性 <Col1> 值中的 & 值被编码为 &amp;。但是 # 字符仍保留为 #，因为它是有效的 XML 字符（而不是特殊的 XML 字符）。

  • 如果元素值或特性值包含任何在 URL 中有特殊意义的特殊 URL 字符，则只能在 DBOBJECT URL 值内对这些字符编码，而且只有当该特殊字符是表或列名的一部分时才对它们编码。在上面的结果中，作为表名 Col#&2 一部分的字符 # 在 DBOJBECT URL 中被编码为 x0023。
G. 指定 ELEMENTS 选项

下面的查询返回客户和订单信息。该查询指定了 ELEMENTS 选项。结果表列映射到子元素。

SELECT Customers.CustomerID, ContactName, OrderID, OrderDate
FROM Customers, Orders
WHERE Customers.CustomerID = Orders.CustomerID
ORDER BY Customers.CustomerID
FOR XML AUTO, ELEMENTS

结果如下：

<Customers>
  <CustomerID>ALFKI</CustomerID>
  <ContactName>Maria Anders</ContactName>
     <Orders>
       <OrderID>10835</OrderID>
       <OrderDate>1998-01-15T00:00:00</OrderDate>
     </Orders>
     <Orders>
       <OrderID>10952</OrderID>
       <OrderDate>1998-03-16T00:00:00</OrderDate>
     </Orders>
</Customers>

在 element-centric（以元素为中心的）映射中，可以在查询中为不同的列指定相同的别名。这导致具有相同名称的多个子元素（这在 attribute-centric 即以特性为中心的映射中是不允许的），例如：

SELECT FirstName name, LastName name
FROM Employees
FOR XML AUTO, EXPLICIT

下面是部分结果：

<Employees>
  <name>Nancy</name>
  <name>Davolio</name>
</Employees>
 ...

请参见

SELECT


使用 EXPLICIT 模式

在 EXPLICIT 模式中，查询书写器控制由执行查询所返回的 XML 文档的形式。必须以特定的方式编写查询，将有关预期嵌套的附加信息显式指定为查询的一部分。可用 directive 在列级指定附加的配置。当指定 EXPLICIT 模式时，必须负责确保生成的 XML 符合语法规则并且有效（对于 XML-DATA 架构）。

处理 EXPLICIT 模式查询和通用表

EXPLICIT 模式将查询执行所得到的行集转换为 XML 文档。为使 EXPLICIT 模式生成 XML 文档，行集必须具有特定的格式。这需要以某种方式编写 SELECT 查询以生成具有特定格式的行集（称为通用表），可对该行集进行处理以生成请求的 XML 文档。

EXPLICIT 模式首先要求查询生成两个元数据列：

  • 在 SELECT 子句中指定的第一列必须是命名 (Tag) 标记号。Tag 列存储当前元素的标记号。Tag 是整型数据类型。

  • 指定的第二列必须是父元素的命名 (Parent) 标记号。Parent 列存储父元素的标记号。Tag 是整型数据类型。

这些列用于确定 XML 树中的父子层次结构。这些信息随后用于生成预期的 XML 树。如果存储在 Parent 列中的父标记值是 0 或 NULL，则将行放置在 XML 层次结构的顶层。

通用表的其余部分充分描述所得到的 XML 文档。下图是通用表的一个示例，其中显示了 <Customer>、<Order> 和 <OrderDetail> 的嵌套。

行集（通用表）中的数据垂直分区成组。每组成为结果中的一个 XML 元素。

生成该示例通用表的查询在 EXPLICIT 模式下生成下面的 XML 文档（下面的示例之一描述此查询）。只显示了部分输出：

<Customer cid="C1" name="Janine">
   <Order id="O1" date="1/20/1996">
      <OrderDetail id="OD1" pid="P1"/>
      <OrderDetail id="OD2" pid="P2"/>
   </Order>
   <Order id="O2" date="3/29/1997">
   ...
</Customer>

FOR XML EXPLICIT 模式要求 SELECT 查询以某种方式指定通用表中的列名。它要求 SELECT 查询将元素名与标记号相关联，并提供通用表列名中的特性名（默认情况下是特性名）。此外，若要得到与父实例相关联的正确子实例，需要对行集排序，使子实例紧跟在它的父实例后。

简言之，通用表的列名、Tag 和 Parent 元列中的值以及通用表格式的数据所提供的信息都用于生成所期望的 EXPLICIT 模式的 XML 文档。

指定通用表中的列名

SELECT 查询还必须指定通用表中的列名。通用表中的列名使用 XML 类属标识符和特性名进行编码。通用表列名中的元素名、特性名和其它转换信息的编码被指定为：

ElementName!TagNumber!AttributeName!Directive

参数

ElementName

是所得到的元素类属标识符（例如，如果将 Customers 指定为 ElementName，则 <Customers> 是元素标记）。

TagNumber

是元素的标记号。借助于通用表中的两个元数据列（Tag 和 Parent），TagNumber 用于表示 XML 树中的 XML 元素嵌套。每个 TagNumber 都准确对应于一个 ElementName。

AttributeName

是 XML 特性的名称（如果没有指定 Directive）或包含的元素名（如果 Directive 是 xml、cdata 或 element）。如果指定 Directive，则 AttributeName 可以为空。这种情况下，列中包含的值直接由具有指定 ElementName 的元素所包含。

Directive

是可选命令。如果没有指定 Directive，则必须指定 AttributeName。如果没有指定 AttributeName 且没有指定 Directive（如 Customer!1），则表示元素命令（如 Customer!1!!element）且包含数据。

Directive 有两种用途。该选项用于分别使用关键字 ID、IDREF 和 IDREFS 对 ID、IDREF 和 IDREFS 进行编码。还用于表示如何使用关键字 hide、element、xml、xmltext 和 cdata 将字符串数据映射到 XML。大多数情况下允许在这些组中组合指令，但是不能在组本身中进行组合。

ID
可将元素特性指定为 ID 类型的特性。然后可以使用 IDREF 和 IDREFS 特性引用它们，以启用文档内的链接。但是，如果没有请求 XMLDATA，则此关键字无效。
IDREF
指定为 IDREF 的特性可用于引用 ID 类型的特性，以启用文档内的链接。但是，如果没有请求 XMLDATA，则此关键字无效。
IDREFS
指定为 IDREFS 的特性可用于引用 ID 类型的特性，以启用文档内的链接。但是，如果没有请求 XMLDATA，则此关键字无效。
hide
不显示特性。这对于按照不出现在结果中的特性对结果进行排序可能很有用。
element
不生成特性。而是生成具有指定名称的包含元素（如果没有指定特性名则直接生成包含元素）。包含数据被编码为实体（例如，字符 < 变成 &lt;）。该关键字可以与 ID、IDREF 或 IDREFS 组合。
xml
除了不进行实体编码外，该命令与元素命令相同（例如，字符 < 仍是 <）。除了 hide 外，该命令不能与任何其它命令一起使用。
xmltext
列内容应包在单个标记内，以便与文档的其它部分集成。在提取 OPENXML 存储在列中的溢出（未用完的）XML 数据时该命令很有用。有关更多信息，请参见使用 OPENXML 编写 XML。

如果指定了 AttributeName，则标记名由指定名称替换；否则通过将内容放在容器的起始处而不进行实体编码，将特性追加到包含元素的当前特性列表。含有该命令的列必须是文本类型（varchar、nvarchar、char、nchar、text、ntext）。该命令只能与 hide 一起使用。在提取存储在列中的溢出数据时该命令很有用。

如果内容不是有效的 XML，则该行为不明确。

cdata
通过用 CDATA 节环绕数据来包含数据。不对内容进行实体编码。原始数据类型必须是文本类型（varchar、nvarchar、text、ntext）。该命令只能与 hide 一起使用。当使用该命令时，不应指定 AttributeName。
示例

可以使用 SQL 查询分析器执行下列示例中的查询。若要使用 HTTP 执行这些查询，请参见使用 HTTP 访问 SQL Server。

示例 A 和 B 详细说明了编写使用 EXPLICIT 模式的查询的过程。该过程适用于后面的其它示例。

A. 检索客户和订单信息

下例检索客户和订单信息。假定希望生成下面的层次结构：

<Customer CustomerID="ALFKI">

<Order OrderID=10643>
<Order OrderID=10692>

...

</Customer>
<Customer CustomerID="ANATR" >

<Order OrderID=10308 >
<Order OrderID=10625 >

...

</Customer>

生成所得到的 XML 树的查询生成通用表，该表包含两个元数据列：Tag 和 Parent。因此，在指定查询时 SELECT 子句必须指定这两列。这两列中的值用于生成 XML 层次结构。

<Customer> 元素位于顶层。在下面的示例中，指派给此元素的 Tag 值为 1（该值可以是任何数字，但是有唯一的数字与每个元素名相关联）。因为 <Customer> 是顶层元素，所以其 Parent 标记值为 NULL。

<Order> 元素是 <Customer> 元素的子元素。因此，<Order> 元素的 Parent 标记值为 1（将 <Customer> 标识为其父元素）。指派给 <Order> 元素的 Tag 值为 2。

可使用两个 SELECT 语句编写查询并使用 UNION ALL 组合这两个语句的结果：

  • 在第一个 SELECT 语句中，获取所有 <Customer> 元素及其特性值。在含有多个 SELECT 语句的查询中，只使用在第一个查询中指定的列名（通用表列名）。忽略在第二个 SELECT 语句中指定的列名。因此，指定 XML 元素和特性名的通用表的列名包含在下面的查询中：
    SELECT 1                    as Tag,
         NULL                 as Parent,
         Customers.CustomerID as [Customer!1!CustomerID],
         NULL                 as [Order!2!OrderID]
FROM Customers
  • 在第二个查询中检索所有 <Order> 元素及其特性值：
    SELECT 2,
         1,
         Customers.CustomerID,
         Orders.OrderID
FROM Customers, Orders
WHERE Customers.CustomerID = Orders.CustomerID
  • 使用 UNION ALL 组合此查询中的两个 SELECT 语句。

  • 以只进方式对通用表行集（包含所有数据和元数据）逐行扫描，以生成所得到的 XML 树。为了输出正确的 XML 文档层次结构，指定通用表中的行顺序也很重要。为此可在查询中使用 ORDER BY 子句。

  • 下面是最终查询：
    SELECT 1                    as Tag,
         NULL                 as Parent,
         Customers.CustomerID as [Customer!1!CustomerID],
         NULL                 as [Order!2!OrderID]
FROM Customers

UNION ALL
SELECT 2,
         1,
         Customers.CustomerID,
         Orders.OrderID
FROM Customers, Orders
WHERE Customers.CustomerID = Orders.CustomerID
ORDER BY [Customer!1!CustomerID], [Order!2!OrderID]
FOR XML EXPLICIT

所得到的通用表是有四列的表。为了举例说明，只显示几行。

Tag | Parent | Customer!1!CustomerID | Order!2!OrderID
1 | NULL | ALFKI | NULL
2 | 1 | ALFKI | 10643
2 | 1 | ALFKI | 10692
2 | 1 | ALFKI | 10702
2 | 1 | ALFKI | 11011
2 | 1 | ALFKI | ...
1 | NULL | ANATR | NULL
2 | 1 | ANATR | 10308
2 | 1 | ANATR | 10625
2 | 1 | ANATR | ...

下面描述处理通用表中的行以生成所得到的 XML 树：

  1. 第一行标识 Tag 值 1。标识所有含有 Tag 值 1 的列。只有一列含有 Tag 值 1：Customer!1!CustomerID。此列名由元素名 (Customer)、标记号 (1) 和特性名 (CustomerID) 组成。因此，创建 <Customer> 元素并向其添加特性 CustomerID。然后将该列值指派为该特性值。

  2. 第二行有 Tag 值 2。因此，标识所有含有 Tag 值 2 的列。只有一列含有 Tag 值 2：Order!2!OrderID。此列名由元素名 (Order)、标记号 (2) 和特性名 (OrderID) 组成。该行也将 <Customer> 标识为其父元素（Parent 值为 1）。结果，创建 <Order> 元素作为 <Customer> 元素的子元素并向其添加特性 OrderID。然后将该列值指派为该特性值。

  3. 以相同的方式处理后面含有 Tag 值 2 的所有行。

  4. 标识含有 Tag 值 1 的某行。标识含有 Tag 值 1 的 Customer!1!CustomerID 列。该列标识没有父元素（Parent 为 NULL）的 <Customer> 元素。因而，关闭前面的 <Order> 标记和 <Customer> 标记。打开新的 <Customer> 标记并重复此过程。

因为没有在查询中指定 Directive，所以特性名是 XML 特性的名称。下面是部分结果集：

<Customer CustomerID="ALFKI">
  <Order OrderID="10643" />
  <Order OrderID="10692" />
  <Order OrderID="10702" />
  <Order OrderID="11011" />
</Customer>
<Customer CustomerID="ANATR">
  <Order OrderID="10308" />
  <Order OrderID="10625" />
</Customer>
B. 指定元素命令

下例检索客户和订单信息。假定希望生成下面的层次结构：（注意 <OrderID> 是 <Order> 的子元素而不是特性）：

<Customer CustomerID="ALFKI">
   <Order OrderDate="1997-08-25T00:00:00">
      <OrderID>10643</OrderID>
   </Order>
   <Order OrderDate="1997-10-03T00:00:00">
      <OrderID>10692</OrderID>
   </Order>
    ...
</Customer>

<Customer> 元素位于顶层。在下例中，为 <Customer> 指派 Tag 值 1。因为 <Customer> 为顶层元素，所以其 Parent 标记值为 NULL。

<Order> 元素是 <Customer> 元素的子元素。因此，<Order> 元素的 Parent 标记值为 1（将 <Customer> 标识为其父元素），并为其指派 Tag 值 2。

<Order> 元素具有作为包含元素（不是特性）的 <OrderID>。因此，在检索该值时，必须指定 element 命令。

可使用两个 SELECT 语句编写查询，并使用 UNION ALL 组合这两个语句的结果：

  • 在第一个 SELECT 语句中，获取所有 <Customer> 元素及其特性值。在含有多个 SELECT 语句的查询中，只使用在第一个查询中指定的列名（通用表列名）。忽略在第二个 SELECT 语句中指定的列名。因此，指定 XML 元素和特性名的通用表的列名包含在下面的查询中：
    SELECT 1                    as Tag,
         NULL                 as Parent,
         Customers.CustomerID as [Customer!1!CustomerID],
         NULL                 as [Order!2!OrderID!element],
         NULL                 as [Order!2!OrderDate]
FROM Customers

  • 在第二个查询中检索所有 <Order> 元素及其特性值。因为需要使用 ORDER BY 子句对含有子元素的父元素进行分组，所以该查询选择 Customers.CustomerID。

    SELECT 2, 1,
         Customers.CustomerID,
         Orders.OrderID,
         Orders.OrderDate
FROM Customers, Orders
WHERE Customers.CustomerID = Orders.CustomerID

    •

  • 使用 UNION ALL 组合此查询中的两个 SELECT 语句。

    •

  • 使用 ORDER BY 子句指定所生成的通用表行集中的行顺序。

    •

  • 下面是最终查询：

    SELECT 1                    as Tag,
         NULL                 as Parent,
         Customers.CustomerID as [Customer!1!CustomerID],
         NULL                 as [Order!2!OrderID!element],
         NULL                 as [Order!2!OrderDate]
FROM Customers

UNION ALL
SELECT 2,
         1,
         Customers.CustomerID,
         Orders.OrderID,
         Orders.OrderDate
FROM Customers, Orders
WHERE Customers.CustomerID = Orders.CustomerID
ORDER BY [Customer!1!CustomerID], [Order!2!OrderID!element]
FOR XML EXPLICIT

    •

所得到的通用表是有五列的表。为了举例说明，只显示几行。

Tag | Parent | Customer!1!CustomerID | Order!2!OrderID!element | Order!2!OrderDate
1 | NULL | ALFKI | NULL | NULL
2 | 1 | ALFKI | 10692 | 1997-10-03T00:00:00
2 | 1 | ALFKI | 10702 | 1997-10-13T00:00:00
2 | 1 | ALFKI | 10835 | 1998-01-15T00:00:00
... | ... | ... | ... | ...
1 | NULL | ANATR | 10308 | 1996-09-18T00:00:00
1 | NULL | ANATR | ... | ...

下面描述对行集中的行进行处理以生成所得到的 XML 树：

  1. 第一行标识 Tag 值 1。因此，标识所有含有 Tag 值 1 的列。只有一列含有 Tag 值 1： Customer!1!CustomerID 列。此列名由元素名 (Customer)、标记号 (1) 和特性名 (CustomerID) 组成。因此，创建 <Customer> 元素并向其添加特性 CustomerID。然后将该列值指派为该特性值。

    2.

  2. 第二行含有 Tag 值 2。标识含有 Tag 值 2 的所有列。有两列含有 tag 号 2：Order!2!OrderID!element 和 Order!2!OrderDate。

    • 列名 Order!2!OrderDate 由元素名 (Order)、标记号 (2) 和特性名 (OrderDate) 组成。该行将 <Customer> 标识为其父元素（Parent 值为 1）。因此，创建 <Order> 元素作为 <Customer> 元素的子元素并向其添加特性 OrderID。将该列值指派为该特性值。

      •

    • 列名 Order!2!OrderID!element 由命令 (element) 组成。因此，生成一个包含元素 (<OrderID>)。将该列值指派为该元素值。
      •

    3.

  3. 以相同的方式处理后面含有 Tag 值 2 的所有行。

    4.

  4. 标识含有 Tag 值 1 的某行。标识含有 Tag 值 1 的 Customer!1!CustomerID 列。该列标识没有父元素（Parent 为 NULL）的 <Customer> 元素。因而，关闭前面的 <Order> 标记和 <Customer> 标记。打开新的 <Customer> 标记并重复此过程。

    说明  在此查询中，如果更改列名 (Order!2!OrderID!element) 以便不指定特性名 (Order!2!!element)，则该查询直接生成包含元素。

    5.

C. 指定 element 命令和实体编码

如果将 directive 设置为 element，则对包含数据进行实体编码。例如，如果在 Customers 表中有一位客户联系人的姓名是 Mar<ia Anders，则下面的查询将对所包含的数据进行编码：

--Update customer record.
UPDATE Customers
SET ContactName='Mar<ia Anders'
WHERE ContactName='Maria Anders'
GO

下面的查询返回客户 ID 和联系人姓名信息。

编写生成通用表的查询的过程和对通用表行集进行处理以生成所得到的 XML 文档的过程，与在示例 A 或示例 B 中描述的过程相似。

SELECT 1 as Tag, NULL as Parent,
       Customers.CustomerID as [Customer!1!CustomerID],
       Customers.ContactName as [Customer!1!ContactName!element]
FROM Customers
ORDER BY [Customer!1!CustomerID]
FOR XML EXPLICIT
GO
-- set the value back to original
UPDATE Customers
SET ContactName='Maria Anders'
WHERE ContactName='Mar<ia Anders'
GO

下面显示部分结果。因为在查询中指定了 element 命令，所以指定的特性名是包含元素的名称。也对 ContactName 进行实体编码（将 ContactName 中的 < 字符返回为 &lt;）

<Customer CustomerID="ALFKI">
  <ContactName>Mar&lt;ia Anders</ContactName>
</Customer>
<Customer CustomerID="ANATR">
  <ContactName>Ana Trujillo</ContactName>
</Customer>

D. 指定 xml 命令

除了不对包含数据进行实体编码外（"<"字符仍是"<"），xml 命令与 element 命令相似。例如，如果 Customers 表中有一位客户联系人的姓名是 Mar<ia Andears，则下面的查询不对包含数据进行实体编码，并将生成无效的 XML 文档。

-- Update a customer record.
UPDATE Customers
SET ContactName='Mar<ia Anders'
WHERE ContactName='Maria Anders'
GO

下面的查询返回客户 ID 和联系人姓名信息。

编写生成通用表的查询的过程和对通用表行集进行处理以生成所得到的 XML 文档的过程，与在示例 A 或示例 B 中描述的过程相似。

SELECT 1 as Tag, NULL as Parent,
       Customers.CustomerID as [Customer!1!CustomerID],
       Customers.ContactName as [Customer!1!ContactName!xml]
FROM Customers
ORDER BY [Customer!1!CustomerID]
FOR XML EXPLICIT
GO
-- Set customer record back to the original.
UPDATE Customers
SET ContactName='Maria Anders'
WHERE ContactName='Mar<ia Anders'
GO

下面显示部分结果。因为在查询中指定了该命令，所以指定的特性名是包含元素的名称。

<Customer CustomerID="ALFKI">
   <ContactName>Mar<ia Anders</ContactName>
</Customer>
<Customer CustomerID="ANATR">
   <ContactName>Ana Trujillo</ContactName>
</Customer>

E. 指定隐藏命令

下例说明 hide 命令的使用。当希望查询返回一个特性以便对该查询所返回的通用表中的行进行排序，但是不希望该特性出现在最终所得到的 XML 文档中时，该命令很有用。

假定希望生成下面的层次结构，在该结构中 <Customer> 元素按 CustomerID 进行排序，并且在每个 <Customer> 元素中，<Order> 元素按 OrderID 进行排序。注意 OrderID 特性不出现在所得到的 XML 文档中：

<Customer CustomerID="ALFKI">
  <Order OrderDate="1997-08-25T00:00:00" />
  <Order OrderDate="1997-10-03T00:00:00" />
  <Order OrderDate="1997-10-13T00:00:00" />
</Customer>

在这种情况下，为排序而检索 OrderID，但是在为该特性指定列名时指定 hide 命令。结果，OrderID 特性不显示为所得到的 XML 文档的一部分。

编写生成通用表的查询的过程和对通用表行集进行处理以生成所得到的 XML 文档的过程，与在示例 A 或示例 B 中描述的过程相似。

以下是查询语句：

SELECT 1 as Tag,
       NULL as Parent,
       Customers.CustomerID as [Customer!1!CustomerID],
       NULL                 as [Order!2!OrderID!hide],
       NULL                 as [Order!2!OrderDate]
FROM Customers
UNION ALL
SELECT 2,
       1,
       Customers.CustomerID,
       Orders.OrderID,
       Orders.OrderDate
FROM Customers, Orders
WHERE Customers.CustomerID = Orders.CustomerID
ORDER BY [Customer!1!CustomerID], [Order!2!OrderID!hide]
FOR XML EXPLICIT

下面是部分结果。OrderID 特性不在所得到的文档中。

<Customer CustomerID="ALFKI">
  <Order OrderDate="1997-08-25T00:00:00" />
  <Order OrderDate="1997-10-03T00:00:00" />
  <Order OrderDate="1997-10-13T00:00:00" />
</Customer>
<Customer CustomerID="ANATR">
  <Order OrderDate="1996-09-18T00:00:00" />
  <Order OrderDate="1997-08-08T00:00:00" />
</Customer>

F. 指定 cdata 命令

如果将该命令设置为 cdata，则不对包含数据进行实体编码，而是将其放入 CDATA 节。cdata 特性可以是匿名的。

下面的查询将联系人姓名包含在 CDATA 节中。编写生成通用表的查询的过程和对通用表行集进行处理以生成所得到的 XML 文档的过程，与在示例 A 或示例 B 中描述的过程相似。

SELECT 1                     as Tag,
       NULL                  as Parent,
       Customers.CustomerID  as [Customer!1!CustomerID],
       Customers.ContactName as [Customer!1!!cdata]
FROM Customers
ORDER BY [Customer!1!CustomerID]
FOR XML EXPLICIT

下面显示部分结果。包含数据均包在 CDATA 节中，并且不对包含数据进行实体编码（联系人姓名保留 Mar<ia Ande!rs）。

<Customer CustomerID="ALFKI">
  <![CDATA[Maria Anders]]>
</Customer>
<Customer CustomerID="ANATR">
  <![CDATA[Ana Trujillo]]>
</Customer>

G. 指定 ID 和 IDREF 命令

在 XML 文档中，可将元素特性指定为 ID 类型的特性，然后可使用文档中的 IDREF 特性引用它们，从而启用文档内的链接（类似于关系数据库中的主键和外键关系）。

下例中的查询返回由 ID 和 IDREF 特性组成的 XML 文档。下例检索客户和订单信息。该查询将返回下列 XML 文档：

<Customer CustomerID="ALFKI">
  <Order CustomerID="ALFKI" OrderDate="1997-08-25T00:00:00">
    <OrderID>10643</OrderID>
  </Order>
  <Order CustomerID="ALFKI" OrderDate="1997-10-03T00:00:00">
    <OrderID>10692</OrderID>
  </Order>
</Customer>
...

假设还希望使 <Customer> 元素的 CustomerID 特性成为 ID 类型并使 <Order> 元素的 CustomerID 特性成为 IDREF 类型。因为一份订单只属于一位客户，所以指定 IDREF。

编写生成通用表的查询的过程和对通用表行集进行处理以生成所得到的 XML 文档的过程，与在示例 A 或示例 B 中描述的过程相似。该查询只是增加了将命令（Id 和 IDREF）指定为列的一部分。

以下是查询语句：

SELECT 1                    as Tag,
       NULL                 as Parent,
       Customers.CustomerID as [Customer!1!CustomerID!id],
       NULL                 as [Order!2!OrderID!element],
       NULL                 as [Order!2!CustomerID!idref],
       NULL                 as [Order!2!OrderDate]
FROM Customers
UNION ALL
SELECT 2,
       1,
       Customers.CustomerID,
       Orders.OrderID, Orders.CustomerID,
       Orders.OrderDate
FROM Customers, Orders
WHERE Customers.CustomerID = Orders.CustomerID
ORDER BY [Customer!1!CustomerID!id], [Order!2!OrderID!element]
FOR XML EXPLICIT, XMLDATA

在查询中指定的 ID 或 IDREF 命令标记 XML-Data 架构中的元素/特性。在该查询中：

  • 将 ID 命令指定为通用表列名 (Customer!1!CustomerID!id) 的一部分。这使返回的 XML 文档中 <Customer> 元素的 CustomerID 特性成为 ID 类型的特性。在 XML-Data 架构中，dt:type 值是 AttributeType 声明中的 ID。

    •

  • 将 IDREF 命令指定为通用表列名 (Order!2!OrderID!idref) 的一部分。此命令使返回的 XML 文档中 <Order> 元素的 OrderID 特性成为 IDREF 类型的特性。在 XML-Data 架构中，dt:type 值是 AttributeType 声明中的 IDREF。
    •

通过在查询中指定 XMLDATA 选项可获得 XML-Data 架构。注意在查询中指定的 ID 和 IDREF 命令重写 XML-Data 架构中的数据类型。

下面是部分结果。因为在查询中指定了 XMLDATA 架构选项，所以为结果预先设计了架构。

<Schema name="Schema1" xmlns="urn:schemas-microsoft-com:xml-data" xmlns:dt="urn:schemas-microsoft-com:datatypes">
<ElementType name="Customer" content="mixed" model="open">
  <AttributeType name="CustomerID" dt:type="id"/>
  <attribute type="CustomerID"/>
</ElementType>
<ElementType name="Order" content="mixed" model="open">
  <AttributeType name="CustomerID" dt:type="idref"/>
  <AttributeType name="OrderDate" dt:type="dateTime"/>
  <element type="OrderID"/>
  <attribute type="CustomerID"/>
  <attribute type="OrderDate"/>
</ElementType>
<ElementType name="OrderID" content="textOnly" model="closed"
             dt:type="i4"/>
</Schema>
<Customer xmlns="x-schema:#Schema1" CustomerID="ALFKI">
  <Order CustomerID="ALFKI" OrderDate="1997-08-25T00:00:00">
    <OrderID>10643</OrderID>
  </Order>
  <Order CustomerID="ALFKI" OrderDate="1997-10-03T00:00:00">
    <OrderID>10692</OrderID>
  </Order>
</Customer>

H. 指定 ID 和 IDREFS 特性

可以将元素特性指定为 ID 类型的特性，然后可使用 IDREFS 特性引用它们，从而启用文档内的链接（与关系数据库中主键、外键的关系相似）。

下例显示如何将 ID、IDREFS 命令指定为查询中列名的一部分以创建 ID 和 IDREFS 类型的 XML 特性。因为 ID 不能是整型值，所以下例中的 ID 值是投影的类型；前缀用于 ID 值。

在 ORDER BY 子句中，将客户姓名指定为正在排序的特性以显示不是 ID 的特性可用于对结果进行排序。

假设这些表存在于数据库中：

-- Create Customers2 table.
CREATE TABLE Customers2 (CustomerID  int primary key,
             CustomerName varchar(50))
GO
-- Insert records in Customers2 table.
INSERT INTO Customers2 values (1, 'Joe')
INSERT INTO Customers2 values (2, 'Bob')
INSERT INTO Customers2 values (3, 'Mary')
Go
-- Create Orders2 table.
CREATE TABLE Orders2 (OrderID   int primary key,
             CustomerID int references Customers2)
GO
-- Insert records in Orders2 table.
INSERT INTO Orders2 values (5, 3)
INSERT INTO Orders2 values (6, 1)
INSERT INTO Orders2 values (9, 1)
INSERT INTO Orders2 values (3, 1)
INSERT INTO Orders2 values (8, 2)
INSERT INTO Orders2 values (7, 2)
GO

假设某查询返回具有下列层次结构的 XML 文档：

<Cust CustID="1" CustName="Joe" OrderIDList="O-3 O-6 O-9">
   <Order Oid="O-3"/>
   <Order Oid="O-6"/>
   <Order Oid="O-9"/>
</Cust>
<Cust CustID="2" CustName="Bob" OrderIDList="O-7 O-8">
   <Order Oid="O-7"/>
   <Order Oid="O-8"/>
</Cust>
<Cust CustID="3" CustName="Mary" OrderIDList="O-5">
   <Order Oid="O-5"/>
</Cust>

<Cust> 元素的 OrderIDList 特性是引用 <Order> 元素的 Oid 特性的多值特性。若要建立此链接，必须将 Oid 特性声明为 ID 类型，并且必须将 <Cust> 元素的 OrderIDList 特性声明为 IDREFS 类型。因为一个客户可下许多订单，所以使用 IDREFS 类型。

编写生成通用表的查询的过程和对通用表行集进行处理以生成所得到的 XML 文档的过程，与在示例 A 或示例 B 中描述的过程相似。该查询只是增加了将命令（Id 和 IDREFS）指定为列的一部分。

以下是查询语句：

-- Generate Customer element without IDREFS attribute.
SELECT 1            AS tag,
       NULL         AS parent,
       CustomerID   AS "Cust!1!CustID",
       CustomerName AS "Cust!1!CustName",
       NULL         AS "Cust!1!OrderIDList!idrefs",
       NULL         AS "Order!2!Oid!id"
FROM Customers2
UNION ALL
-- Now add the IDREFS. Note that Customers2.CustomerName
-- is repeated because it is listed in the ORDER BY clause
-- (otherwise, NULL would suffice).
SELECT 1 AS tag,
       NULL AS parent,
       Customers2.CustomerID,
       Customers2.CustomerName,
       'O-'+CAST(Orders2.OrderID as varchar(5)),
       NULL
FROM Customers2 join Orders2  on Customers2.CustomerID = Orders2.CustomerID

UNION ALL
-- Now add the subelements (Orders2).
-- Customers2.CustomerID is repeated because it is the parent key.
-- Customers2.CustomerName is repeated because it is listed
-- in the ORDER BY clause.
SELECT 2 AS tag,
       1 AS parent,
       Customers2.CustomerID,
       Customers2.CustomerName,
       NULL,
       'O-'+CAST(Orders2.OrderID as varchar(5))
FROM Customers2 JOIN Orders2 ON Customers2.CustomerID = Orders2.CustomerID

-- Now order by name and by key. No order on the last column
-- is required because the key of Orders2 is not a parent.
ORDER BY "Cust!1!CustID", "Order!2!Oid!id", "Cust!1!OrderIDList!idrefs"
FOR XML EXPLICIT, XMLDATA

在查询中指定的 ID 或 IDREFS 命令标记 XML-Data 架构中的元素/特性。在该查询中：

  • 将 ID 命令指定为通用表列名 (Order!2!Oid!id) 的一部分。这使返回的 XML 文档中 <Order> 元素的 Oid 特性成为 ID 类型的特性。在 XML-Data 架构中，dt:type 值是 AttributeType 声明中的 ID。

    •

  • 将 IDREF 命令指定为通用表列名 (Cust!1!OrderIDList!idrefs) 的一部分。这使返回的 XML 文档中 <Cust> 元素的 OrderIDList 特性成为 IDREF 类型的特性。在 XML-Data 架构中，dt:type 值是 AttributeType 声明中的 IDREFS。
    •

通过在查询中指定 XMLDATA 选项可获得 XML-Data 架构。注意在查询中指定的 ID 和 IDREFS 命令重写 XML-Data 架构中的数据类型。

结果如下：

<Schema name="Schema8" xmlns="urn:schemas-microsoft-com:xml-data"
xmlns:dt="urn:schemas-microsoft-com:datatypes">
<ElementType name="Cust" content="mixed" model="open">
  <AttributeType name="CustID" dt:type="i4"/>
  <AttributeType name="CustName" dt:type="string"/>
  <AttributeType name="OrderIDList" dt:type="idrefs"/>
  <attribute type="CustID"/>
  <attribute type="CustName"/>
  <attribute type="OrderIDList"/>
 </ElementType>
 <ElementType name="Order" content="mixed" model="open">
  <AttributeType name="Oid" dt:type="id"/>
  <attribute type="Oid"/>
 </ElementType>
 </Schema>
 <Cust xmlns="x-schema:#Schema8" CustID="1" CustName="Joe"
       OrderIDList="O-3 O-6 O-9">
  <Order Oid="O-3"/>
  <Order Oid="O-6"/>
  <Order Oid="O-9"/>
 </Cust>
 <Cust xmlns="x-schema:#Schema8" CustID="2" CustName="Bob"
       OrderIDList="O-7 O-8">
  <Order Oid="O-7"/>
  <Order Oid="O-8"/>
 </Cust>
 <Cust xmlns="x-schema:#Schema8" CustID="3" CustName="Mary"
       OrderIDList="O-5">
  <Order Oid="O-5"/>
 </Cust>

I. 指定 xmltext 命令

下例显示如何在使用 EXPLICIT 模式的 SELECT 语句中使用 xmltext 命令解决溢出列中的数据。

请考察 Person 表。该表含有存储 XML 文档未用完部分的 Overflow 列。

CREATE TABLE Person(PersonID varchar(5), PersonName varchar(20), Overflow nvarchar(200))
INSERT INTO Person VALUES ('P1','Joe',N'<SomeTag attr1="data">content</SomeTag>')
INSERT INTO Person VALUES ('P2','Joe',N'<SomeTag attr2="data"/>')
INSERT INTO Person VALUES ('P3','Joe',N'<SomeTag attr3="data" PersonID="P">content</SomeTag>')

下面的查询从 Person 表中检索列。对于 Overflow 列，没有指定 AttributeName，但是将 directive 设置成 xmltext 作为提供通用表列名的一部分。

SELECT 1 as Tag, NULL as parent,
   PersonID as [Parent!1!PersonID],
   PersonName as [Parent!1!PersonName],
   overflow as [Parent!1!!xmltext] -- No AttributeName; xmltext directive
FROM Person
FOR XML EXPLICIT

因为没有为 Overflow 列指定 AttributeName 且指定了 xmltext 命令，所以在所得到的 XML 文档中将 <overflow> 元素中的特性附加到包含 <Parent> 元素的特性列表中，并且因为 <xmltext> 元素中的 PersonID 特性与在同一元素级上检索的 PersonID 特性发生冲突，所以忽略 <xmltext> 元素中的特性（即使 PersonID 为 NULL）。通常情况下，特性将替代溢出中具有相同名称的特性。

结果如下：

<Parent PersonID="P1" PersonName="Joe" attr1="data">
content</Parent>
<Parent PersonID="P2" PersonName="Joe" attr2="data">
</Parent>
<Parent PersonID="P3" PersonName="Joe" attr3="data">
content</Parent>

如果溢出数据含有子元素且指定了上述查询，则添加 Overflow 列中的子元素作为所包含的 <Parent> 元素的子元素。

例如，更改 Person 表中的数据以使 Overflow 列现在含有子元素：

TRUNCATE TABLE Person
INSERT INTO Person VALUES ('P1','Joe',N'<SomeTag attr1="data">content</SomeTag>')
INSERT INTO Person VALUES ('P2','Joe',N'<SomeTag attr2="data"/>')
INSERT INTO Person VALUES ('P3','Joe',N'<SomeTag attr3="data" PersonID="P"><name>content</name></SomeTag>')

如果执行上述查询，则添加 <xmltext> 元素中的子元素作为所包含的 <Parent> 元素的子元素。

SELECT 1 as Tag, NULL as parent,
   PersonID as [Parent!1!PersonID],
   PersonName as [Parent!1!PersonName],
   overflow as [Parent!1!!xmltext] -- no AttributeName, xmltext directive
FROM Person
FOR XML EXPLICIT

结果如下：

<Parent PersonID="P1" PersonName="Joe" attr1="data">
content</Parent>
<Parent PersonID="P2" PersonName="Joe" attr2="data">
</Parent>
<Parent PersonID="P3" PersonName="Joe" attr3="data">
<name>content</name></Parent>

如果使用 xmltext 命令指定 AttributeName，则添加 <overflow> 元素的特性作为所包含的 <Parent> 元素的子元素特性。为 AttributeName 指定的名称成为子元素名。

在下面的查询中，与 xmltext 命令一起指定 AttributeName (<overflow>)。

SELECT 1 as Tag, NULL as parent,
   PersonID as [Parent!1!PersonID],
   PersonName as [Parent!1!PersonName],
   overflow as [Parent!1!overflow!xmltext] -- overflow is AttributeName
                                             -- xmltext is directive
FROM Person
FOR XML EXPLICIT

结果如下：

<Parent PersonID="P1" PersonName="Joe">
<overflow attr1="data">
content</overflow>
</Parent>
<Parent PersonID="P2" PersonName="Joe">
<overflow attr2="data"/>
</Parent>
<Parent PersonID="P3" PersonName="Joe">
<overflow attr3="data" PersonID="P">
<name>content</name></overflow>
</Parent>

在下面的查询元素中，为 PersonName 特性指定 directive。这将导致将 PersonName 添加为所包含的 <Parent> 元素的子元素。<xmltext> 的特性仍附加到所包含的 <Parent> 元素。<overflow> 元素的内容（子元素等）附加到所包含的 <Parent> 元素的其它子元素。

SELECT 1      as Tag, NULL as parent,
   PersonID   as [Parent!1!PersonID],
   PersonName as [Parent!1!PersonName!element], -- element directive
   overflow   as [Parent!1!!xmltext]
FROM Person
FOR XML EXPLICIT

结果如下：

<Parent PersonID="P1" attr1="data">
   content   <PersonName>Joe</PersonName>
</Parent>
<Parent PersonID="P2" attr2="data">
   <PersonName>Joe</PersonName>
</Parent>
<Parent PersonID="P3" attr3="data">
   <name>content</name>   <PersonName>Joe</PersonName>
</Parent>

如果 xmltext 列数据包含根元素特性，这些特性将不在 XML-Data 架构中显示，并且 MSXML 分析程序不验证所得到的 XML 文档片段的有效性，例如：

SELECT 1 as Tag,
       0 as Parent,
       N'<overflow a="1"/>' as 'overflow!1!!xmltext'
FOR XML EXPLICIT, xmldata

结果如下。注意在返回的架构中缺少溢出特性 a。

<Schema name="Schema12" xmlns="urn:schemas-microsoft-com:xml-data"
    xmlns:dt="urn:schemas-microsoft-com:datatypes">
 <ElementType name="overflow" content="mixed" model="open">
 </ElementType>
</Schema>
 <overflow xmlns="x-schema:#Schema12" a="1"> </overflow>

J. 获得由客户、订单和订单详细信息组成的 XML 文档

下例中的查询生成通用表行集，前面的主题从概念上对通用表行集进行了讨论。

假设将要生成的层次结构如下：

<Customer cid="C1" name="Janine">
   <Order id="O1" date="1/20/1996">
      <OrderDetail id="OD1" pid="P1"/>
      <OrderDetail id="OD2" pid="P2"/>
   </Order>
   <Order id="O2" date="3/29/1997">
   ...
</Customer>

编写生成通用表的查询的过程和对通用表行集进行处理以生成所得到的 XML 文档的过程，与在示例 A 或示例 B 中描述的过程相似。

SELECT 1             as Tag,
       NULL          as Parent,
       C.CustomerID  as [Customer!1!cid],
       C.ContactName as [Customer!1!name],
       NULL          as [Order!2!id],
       NULL          as [Order!2!date],
       NULL          as [OrderDetail!3!id!id],
       NULL          as [OrderDetail!3!pid!idref]
FROM Customers C
UNION ALL
SELECT 2 as Tag,
       1 as Parent,
       C.CustomerID,
       NULL,
       O.OrderID,
       O.OrderDate,
       NULL,
       NULL
FROM Customers C, Orders O
WHERE C.CustomerID = O.CustomerID
UNION ALL
SELECT 3 as Tag,
       2 as Parent,
       C.CustomerID,
       NULL,
       O.OrderID,
       NULL,
       OD.OrderID,
       OD.ProductID
FROM Customers C, Orders O, [Order Details] OD
WHERE C.CustomerID = O.CustomerID
AND O.OrderID = OD.OrderID
ORDER BY [Customer!1!cid], [Order!2!id]
FOR XML EXPLICIT

下面是部分结果：

<Customer cid="ALFKI" name="Maria Anders">
   <Order id="10643" date="1997-08-25T00:00:00">
      <OrderDetail id="10643" pid="28"></OrderDetail>
      <OrderDetail id="10643" pid="39"></OrderDetail>
   </Order>
   <Order id="10692" date="1997-10-03T00:00:00">
      <OrderDetail id="10692" pid="63"></OrderDetail>
   </Order>
   <Order id="10702" date="1997-10-13T00:00:00">
      <OrderDetail id="10702" pid="3"></OrderDetail>
      <OrderDetail id="10702" pid="76"></OrderDetail>
   </Order>
</Customer>

请参见

SELECT


在查询中指定 XMLDATA 架构选项

在查询中指定 XMLDATA 的主要目的是检索 XML 数据类型信息，而这些信息可用于需要数据类型的情况（如在处理数字表达式时）。否则，XML 文档中的全部信息都是文本化字符串。XML-Data 架构的生成是服务器上的一种开销并有可能影响性能，因此只应在需要数据类型时才使用。

如果从其中检索值的数据库列是 sql_variant 类型，则在 XML-Data 架构中没有数据类型信息。如果给定的查询用相同的名称指派不同的 XML 元素，则 XMLDATA 可能生成非法的 XML-Data 架构。这是因为没有解决元素名冲突和数据类型名冲突（可以有两个名称相同但数据类型不同的元素）。

示例
A. 指定 XMLDATA 架构选项

该查询指定 XMLDATA 架构选项。该查询返回客户和订单信息。

SELECT Customers.CustomerID, ContactName,
       Orders.OrderID, OrderDate, Orders.CustomerID,
       ProductID, Quantity
FROM Customers, Orders, [Order Details]
WHERE Customers.CustomerID = Orders.CustomerID
AND Orders.OrderID = [Order Details].OrderID
ORDER BY Customers.CustomerID, Orders.OrderID
FOR XML AUTO, XMLDATA

下面是部分结果。在结果中生成并预先设计 XML-Data 架构。表名 [Order Details] 是无效的 XML 名称，因为在此表名中有空格。将此无效的字符转换成转义数字编码。

<Schema name="Schema1" xmlns="urn:schemas-microsoft-com:xml-data" xmlns:dt="urn:schemas-microsoft-com:datatypes">
<ElementType name="Customers" content="eltOnly" model="closed">
<element type="Orders"/>
  <AttributeType name="CustomerID" dt:type="string"/>
  <AttributeType name="ContactName" dt:type="string"/>
  <attribute type="CustomerID"/>
  <attribute type="ContactName"/>
</ElementType>
<ElementType name="Orders" content="eltOnly" model="closed">
<element type="Order_0020_Details"/>
  <AttributeType name="OrderID" dt:type="i4"/>
  <AttributeType name="OrderDate" dt:type="dateTime"/>
  <AttributeType name="CustomerID" dt:type="string"/>
  <attribute type="OrderID"/>
  <attribute type="OrderDate"/>
  <attribute type="CustomerID"/>
</ElementType>
<ElementType name="Order_0020_Details" content="empty" model="closed">
  <AttributeType name="ProductID" dt:type="i4"/>
  <AttributeType name="Quantity" dt:type="i2"/>
  <attribute type="ProductID"/>
  <attribute type="Quantity"/>
</ElementType>
</Schema>
<Customers xmlns="x-schema:#Schema1" CustomerID="ALFKI" ContactName="Maria Anders">
  <Orders OrderID="10643" OrderDate="1997-08-25T00:00:00"
          CustomerID="ALFKI">
    <Order_0020_Details ProductID="28" Quantity="15"/>
    <Order_0020_Details ProductID="39" Quantity="21"/>
  </Orders>
  <Orders OrderID="10692" OrderDate="1997-10-03T00:00:00"
          CustomerID="ALFKI">
    <Order_0020_Details ProductID="63" Quantity="20"/>
  </Orders>
</Customers>

下例中的查询将相同的别名指派给 EmployeeID 和 LastName 列以及在 FROM 子句中指定的 Employees 表：

SELECT EmployeeID emp,
       LastName emp
FROM Employees emp
FOR XML AUTO, ELEMENTS, XMLDATA

只显示所得到的 XML-Data 架构。在该架构中有三个 <emp> 元素。还请注意其中两个 <emp> 元素具有不同的数据类型。

<Schema name="Schema2" xmlns="urn:schemas-microsoft-com:xml-data" xmlns:dt="urn:schemas-microsoft-com:datatypes">
<ElementType name="emp" content="mixed" model="closed">
   <element type="emp"/>
   <element type="emp"/>
</ElementType>
<ElementType name="emp" content="textOnly" model="closed" dt:type="i4"/>
<ElementType name="emp" content="textOnly" model="closed" dt:type="string"/>
</Schema>


使用 OPENXML 编写 XML

OPENXML 是在内存中的 XML 文档上提供行集的 Transact-SQL 关键字。OPENXML 是与表或视图相似的行集提供程序。OPENXML 通过提供 XML 文档内部表示法的行集视图，允许访问 XML 数据，就好象它是关系行集一样。行集中的记录可以存储在数据库表中（类似于表和视图所提供的行集）。

无论行集提供程序（如表、视图或 OPENROWSET）可以在何处作为源出现，都可以在 SELECT 和 SELECT INTO 语句中使用 OPENXML。有关 OPENXML 语法的信息，请参见 OPENXML。

若要使用 OPENXML 编写对 XML 文档的查询，首先必须调用 sp_xml_preparedocument，以分析 XML 文档并返回准备使用的已分析文档的句柄。已分析文档是 XML 文档中各种节点（元素、特性、文本、注释等等）的树型表示法。文档句柄传递到 OPENXML，然后 OPENXML 根据传递给它的参数提供文档的行集视图。

必须通过调用 sp_xml_removedocument 系统存储过程释放内存，以将 XML 文档的内部表示法从内存中删除。

下图说明了此过程。

说明 若要理解 OPENXML，需要熟悉 XPath 查询并理解 XML。有关 Microsoft® SQL Server™ 2000 XPath 支持的更多信息，请参见使用 XPath 查询。

OPENXML 参数

OPENXML 的参数包括：

  • XML 文档句柄 (idoc)

  • 标识要映射到行的节点的 XPath 表达式 (rowpattern)

  • 对要生成的行集的描述

  • 行集列和 XML 节点之间的映射
XML 文档句柄 (idoc)

sp_xml_preparedocument存储过程返回此文档句柄。

XPath 表达式标识将要处理的节点 (rowpattern)

指定为 rowpattern 的 XPath 表达式标识 XML 文档中的节点集。rowpattern 标识的每个节点对应于 OPENXML 所生成的行集中的一行。

XPath 表达式标识的节点可以是 XML 文档中的任何 XML 节点（元素、特性、处理说明等）。如果 rowpattern 标识 XML 文档中的元素集，则所标识的每个元素节点在行集中都占一行。例如，如果 rowpattern 以特性结束，则将为 rowpattern 选定的每个特性节点创建一行。

描述将要生成的行集

必须向 OPENXML 提供行集架构以生成行集。可以使用可选的 WITH 子句指定行集架构。下列选项可用于指定行集架构：

  • 在 WITH 子句中指定完整的架构。

    在指定行集架构时，可指定列名和它们的数据类型，以及它们到 XML 文档的映射。

    可以指定列模式（使用 SchemaDeclaration 中的 ColPattern 参数）。指定的列模式用于将行集列映射到 rowpattern 所标识的 XML 节点并确定映射类型。

    如果没有为列指定 ColPattern，则行集列根据 flags 参数所指定的映射而映射到具有相同名称的 XML 节点。但是如果在 WITH 子句中将 ColPattern 指定为架构描述的一部分，则重写用 flags 参数指定的映射。

  • 在 WITH 子句中指定现有表名。

    可以很容易地指定现有的表名，而 OPENXML 可以使用该表的架构生成行集。

  • 不指定 WITH 子句。

    在这种情况下，OPENXML 以所谓的边缘表格式返回行集。称其为边缘表是因为采用这种表格式时，已分析的 XML 文档树中的每个边缘分别映射到行集中的一行。

    边缘表在单个表中表示 XML 文档的细密结构（例如，元素/特性名、文档层次结构、命名空间、处理说明等）。边缘表格式使您得以获得无法通过元属性表现的附加信息。有关元属性的更多信息，请参见在 OPENXML 中指定元属性。

    边缘表提供的附加信息使您得以存储/查询元素/特性的数据类型、节点类型（元素节点、特性节点或值节点），存储/查询有关 XML 文档结构的信息，并有可能生成 XML 文档管理系统。

    边缘表使您得以编写存储过程，以将 XML 文档视为 BLOB 输入、生成边缘表，然后在最精细的级别上析取并分析文档（查找文档层次结构、元素/特性名、命名空间、处理说明等）。

    当映射到其它关系格式没有意义且 ntext 字段没有提供足够的结构信息时，边缘表还可以用作 XML 文档的存储格式。

    无论何时只要想以其它方式使用 XML 语法分析器检查 XML 文档，都可以使用边缘表获得相同的信息。

    下表描述边缘表的结构。

    列名 | 数据类型 | 描述
    id Bigint 是文档节点的唯一 ID。

    根元素的 ID 值为 0。保留负 ID 值。
    parentid Bigint 标识节点的父节点。此 ID 所标识的父节点不一定是父元素，而是取决于此 ID 所标识节点的子节点的 NodeType。例如，如果节点是文本节点，则其父节点可能是特性节点。

    如果节点位于 XML 文档的顶层，则其 ParentID 为 NULL。
    nodetype Int 标识节点类型。是对应于 XML DOM 节点类型编号的整数（有关节点信息，请参见 DOM）。

    某些节点类型为：

    1 = 元素节点
    2 = 特性节点
    3 = 文本节点
    localname | nvarchar | 给出元素或特性的本地名称。如果 DOM 对象没有名称则为 NULL。
    prefix | nvarchar | 是节点名称的命名空间前缀。
    namespaceuri | nvarchar | 是节点的命名空间 URI。如果值是 NULL，则命名空间不存在。
    datatype | nvarchar | 是元素或特性行的实际数据类型，否则是 NULL。从内嵌 DTD 中或从内嵌架构中推断数据类型。
    prev | Bigint | 是前一个兄弟元素的 XML ID。如果前面没有兄弟元素则为 NULL。
    text | Ntext | 包含文本格式的特性值或元素内容（如果边缘表项不需要值则为 NULL）。

行集列和 XML 节点之间的映射

在 OPENXML 语句中，可以选择指定行集列和 rowpattern 所标识的 XML 节点之间的映射类型（attribute-centric、element-centric）。此信息用于 XML 节点和行集列的相互转换。

有两种方法指定映射（可以同时指定两者）：

  • 使用 flags 参数。

    由 flags 参数所指定的映射采用名称对应，即 XML 节点映射到同名的对应行集列。

  • 使用 ColPattern 参数。

    ColPattern 是 XPath 表达式，被指定为 WITH 子句中的 SchemaDeclaration 的一部分。在 ColPattern 中指定的映射重写 flags 参数所指定的映射。

    ColPattern 可用于指定映射的特殊性质（当映射为 attribute-centric 和 element-centric 时），以重写或增强 flags 所指定的默认映射。

    在下列情况下指定 ColPattern：

    • 行集中的列名不同于它所映射到的元素/特性名。在这种情况下，ColPattern 用于识别行集列映射到的 XML 元素/特性名。

    • 希望将元属性特性映射到列。在这种情况下，ColPattern 用于标识行集列映射到的元属性。有关使用元属性的更多信息，请参见在 OPENXML 中指定元属性。

flags 和 ColPattern 参数都是可选的。如果没有指定映射，则默认情况下使用 attribute-centric 映射（flags 参数的默认值）。

Attribute-centric（以特性为中心的）映射

如果将 OPENXML 中的 flags 参数设置为特性，则特性基于名称对应映射到行集中的列。名称对应表示每个给定名称的 XML 特性都以相同的名称存储在行集中的列内。

如果列名不同于它所映射到的特性名，则必须指定 ColPattern。

如果 XML 特性具有命名空间限定符，则行集中的列名也必须有此限定符。

Element-centric（以元素为中心的）映射

将 OPENXML 中的 flags 参数设置为 2 (XML_ELEMENTS) 将指定 element-centric 映射。除了下列差异外，它与 attribute-centric 映射相似：

  • 除非指定列级模式，否则映射的名称对应（例如，映射到同名 XML 元素的列）选择不复杂的子元素。在检索的情况下，如果子元素是复杂的（包含深一层的子元素），则将列设置为 NULL。忽视子元素的特性值。

  • 具有相同名称的多个子元素将以检索顺序相互重写。在名称相同的情况下，联接父元素将追加子元素。

请参见

sp_xml_preparedocument

sp_xml_removedocument

OPENXML


使用 OPENXML 编写 XML

XML 和 Internet 支持

使用 OPENXML

本主题中的示例说明在创建 XML 文档的行集视图时如何使用 OPENXML。有关 OPENXML 语法的信息，请参见 OPENXML。除在 OPENXML 中指定元属性外，下例显示 OPENXML 的所有特征。有关在 OPENXML 中指定元属性的更多信息，请参见在 OPENXML 中指定元属性。

示例

在检索数据时，用 rowpattern 标识 XML 文档中决定行的节点。rowpattern 用 MSXML XPath 实现中使用的 XPath 模式语言表示。例如，如果模式以元素或特性结束，则将为 rowpattern 选定的每个元素或特性节点创建一行。

flags 值提供默认映射。在 SchemaDeclaration 中如果没有指定 ColPattern，则使用 flags 参数所指定的映射。如果在 SchemaDeclaration 中指定了 ColPattern，则忽略 flags 值。指定的 ColPattern 确定映射（attribute-centric 或 element-centric），还确定在处理溢出/未用完数据时的行为。

A. 执行带 OPENXML 的简单 SELECT 语句

下例中的 XML 文档由 <Customer>、<Order> 和 <OrderDetail> 元素组成。OPENXML 语句从 XML 文档中检索两列行集（CustomerID 和 ContactName）中的客户信息。

首先调用 sp_xml_preparedocument 存储过程以获得文档句柄。此文档句柄传递到 OPENXML。

在 OPENXML 语句中：

  • rowpattern (/ROOT/Customer) 标识要处理的 <Customer> 节点。

  • flags 参数值设置为 1 表示 attribute-centric 映射。因此，XML 特性映射到在 SchemaDeclaration 中定义的行集中的列。

  • 在 SchemaDeclaration 中（在 WITH 子句中），指定的 ColName 值与相应的 XML 特性名相匹配。因此，在 SchemaDeclaration 中不指定 ColPattern 参数。

最后 SELECT 语句检索 OPENXML 所提供的行集中的所有列。

DECLARE @idoc int
DECLARE @doc varchar(1000)
SET @doc ='
<ROOT>
<Customer CustomerID="VINET" ContactName="Paul Henriot">
   <Order OrderID="10248" CustomerID="VINET" EmployeeID="5"
          OrderDate="1996-07-04T00:00:00">
      <OrderDetail ProductID="11" Quantity="12"/>
      <OrderDetail ProductID="42" Quantity="10"/>
   </Order>
</Customer>
<Customer CustomerID="LILAS" ContactName="Carlos Gonzlez">
   <Order OrderID="10283" CustomerID="LILAS" EmployeeID="3"
          OrderDate="1996-08-16T00:00:00">
      <OrderDetail ProductID="72" Quantity="3"/>
   </Order>
</Customer>
</ROOT>'
-- Create an internal representation of the XML document.
EXEC sp_xml_preparedocument @idoc OUTPUT, @doc
-- Execute a SELECT statement using OPENXML rowset provider.
SELECT *
FROM OPENXML (@idoc, '/ROOT/Customer',1)
      WITH (CustomerID  varchar(10),
            ContactName varchar(20))
EXEC sp_xml_removedocument @idoc

结果如下：

CustomerID ContactName
---------- --------------------
VINET      Paul Henriot
LILAS      Carlos Gonzlez

如果在 flags 设置为 2 时（表示 element-centric 映射）执行上述 SELECT 语句，两个客户的 CustomerID 和 ContactName 值将作为 NULL 值返回，因为 <Customer> 元素没有任何子元素。

如果在 XML 文档中，<CustomerID> 和 <ContactName> 是子元素，则 element-centric 映射将检索值。

DECLARE @idoc int
DECLARE @doc varchar(1000)
SET @doc ='
<ROOT>
<Customer>
   <CustomerID>VINET</CustomerID>
   <ContactName>Paul Henriot</ContactName>
   <Order OrderID="10248" CustomerID="VINET" EmployeeID="5" OrderDate="1996-07-04T00:00:00">
      <OrderDetail ProductID="11" Quantity="12"/>
      <OrderDetail ProductID="42" Quantity="10"/>
   </Order>
</Customer>
<Customer>
   <CustomerID>LILAS</CustomerID>
   <ContactName>Carlos Gonzlez</ContactName>
   <Order OrderID="10283" CustomerID="LILAS" EmployeeID="3" OrderDate="1996-08-16T00:00:00">
      <OrderDetail ProductID="72" Quantity="3"/>
   </Order>
</Customer>
</ROOT>'
-- Create an internal representation of the XML document.
EXEC sp_xml_preparedocument @idoc OUTPUT, @doc
-- Execute a SELECT statement using OPENXML rowset provider.
SELECT    *
FROM      OPENXML (@idoc, '/ROOT/Customer',2)
           WITH (CustomerID  varchar(10),
                 ContactName varchar(20))
EXEC sp_xml_removedocument @idoc

结果如下：

CustomerID ContactName
---------- --------------------
VINET      Paul Henriot
LILAS      Carlos Gonzlez
B. 为行集列和 XML 特性/元素间的映射指定 ColPattern

下例说明如何用可选 ColPattern 参数指定 XPath 模式，以在行集列和 XML 特性（及元素）之间提供映射。

下例中的 XML 文档由 <Customer>、<Order> 和 <OrderDetail> 元素组成。OPENXML 语句从该 XML 文档中检索客户和订单信息作为行集（CustomerID、OrderDate、ProdID 和 Qty）。

首先调用 sp_xml_preparedocument 以获得文档句柄。此文档句柄传递到 OPENXML。

在 OPENXML 语句中：

  • rowpattern (/ROOT/Customer/Order/OrderDetail) 标识要处理的 <OrderDetail> 节点。

  • 只是为了举例说明，flags 参数值设置为 2 表示 element-centric 映射。但是 ColPattern 参数所指定的映射重写此映射（ColPattern 所指定的 XPath 模式将行集中的列映射到特性，因此产生 attribute-centric 映射）。

在 SchemaDeclaration（在 WITH 子句内）内，也用 ColName 与 ColType 参数指定 ColPattern。可选的 ColPattern 是指定的 XPath 模式，用以表示：

  • 行集中的 OrderID、CustomerID 和 OrderDate 列映射到 rowpattern 所标识节点的父节点的特性，rowpattern 标识 <OrderDetail> 节点。因此，CustomerID 和 OrderDate 列映射到 <Order> 元素的 CustomerID 和 OrderDate 特性。

  • 行集中的 ProdID 和 Qty 列映射到 rowpattern 所标识节点的 ProductID 和 Quantity 特性。

SELECT 语句于是检索 OPENXML 所提供的行集中的所有列。

DECLARE @idoc int
DECLARE @doc varchar(1000)
SET @doc ='
<ROOT>
<Customer CustomerID="VINET" ContactName="Paul Henriot">
   <Order OrderID="10248" CustomerID="VINET" EmployeeID="5"
           OrderDate="1996-07-04T00:00:00">
      <OrderDetail ProductID="11" Quantity="12"/>
      <OrderDetail ProductID="42" Quantity="10"/>
   </Order>
</Customer>
<Customer CustomerID="LILAS" ContactName="Carlos Gonzlez">
   <Order OrderID="10283" CustomerID="LILAS" EmployeeID="3"
           OrderDate="1996-08-16T00:00:00">
      <OrderDetail ProductID="72" Quantity="3"/>
   </Order>
</Customer>
</ROOT>'
-- Create an internal representation of the XML document.
EXEC sp_xml_preparedocument @idoc OUTPUT, @doc
-- Execute a SELECT stmt using OPENXML rowset provider.
SELECT *
FROM OPENXML (@idoc, '/ROOT/Customer/Order/OrderDetail',2)
      WITH (OrderID     int         '../@OrderID',
            CustomerID  varchar(10) '../@CustomerID',
            OrderDate   datetime    '../@OrderDate',
            ProdID      int         '@ProductID',
            Qty         int         '@Quantity')

结果如下：

OrderID CustomerID        OrderDate          ProdID    Qty
-------------------------------------------------------------
10248      VINET       1996-07-04 00:00:00.000     11       12
10248      VINET       1996-07-04 00:00:00.000     42       10
10283      LILAS       1996-08-16 00:00:00.000     72        3

还可以指定被指定为 ColPattern 的 XPath 模式，以将 XML 元素映射到行集列（产生 element-centric 映射）。在下例中，XML 文档 <CustomerID> 和 <OrderDate> 是 <Orders> 元素的子元素。因为 ColPattern 重写 flags 参数所指定的映射，所以在 OPENXML 中没有指定 flags 参数。

DECLARE @idoc int
DECLARE @doc varchar(1000)
SET @doc ='
<ROOT>
<Customer CustomerID="VINET" ContactName="Paul Henriot">
   <Order EmployeeID="5" >
      <OrderID>10248</OrderID>
      <CustomerID>VINET</CustomerID>
      <OrderDate>1996-07-04T00:00:00</OrderDate>
      <OrderDetail ProductID="11" Quantity="12"/>
      <OrderDetail ProductID="42" Quantity="10"/>
   </Order>
</Customer>
<Customer CustomerID="LILAS" ContactName="Carlos Gonzlez">
   <Order  EmployeeID="3" >
      <OrderID>10283</OrderID>
      <CustomerID>LILAS</CustomerID>
      <OrderDate>1996-08-16T00:00:00</OrderDate>
      <OrderDetail ProductID="72" Quantity="3"/>
   </Order>
</Customer>
</ROOT>'
-- Create an internal representation of the XML document.
EXEC sp_xml_preparedocument @idoc OUTPUT, @doc
-- Execute a SELECT stmt using OPENXML rowset provider.
SELECT *
FROM OPENXML (@idoc, '/ROOT/Customer/Order/OrderDetail')
      WITH (CustomerID  varchar(10)   '../CustomerID',
            OrderDate   datetime      '../OrderDate',
            ProdID      int           '@ProductID',
            Qty         int           '@Quantity')
EXEC sp_xml_removedocument @idoc
组合 attribute-centric 映射和 element-centric 映射

在下例中，flags 参数设置为 3 表示应使用 attribute-centric 映射和 element-centric 映射。在这种情况下，首先应用 attribute-centric 映射，然后对所有未处理的列应用 element-centric 映射。

DECLARE @idoc int
DECLARE @doc varchar(1000)
SET @doc ='
<ROOT>
<Customer CustomerID="VINET"  >
     <ContactName>Paul Henriot</ContactName>
   <Order OrderID="10248" CustomerID="VINET" EmployeeID="5"
          OrderDate="1996-07-04T00:00:00">
      <OrderDetail ProductID="11" Quantity="12"/>
      <OrderDetail ProductID="42" Quantity="10"/>
   </Order>
</Customer>
<Customer CustomerID="LILAS" >
     <ContactName>Carlos Gonzlez</ContactName>
   <Order OrderID="10283" CustomerID="LILAS" EmployeeID="3"
          OrderDate="1996-08-16T00:00:00">
      <OrderDetail ProductID="72" Quantity="3"/>
   </Order>
</Customer>
</ROOT>'

-- Create an internal representation of the XML document.
EXEC sp_xml_preparedocument @idoc OUTPUT, @doc

-- Execute a SELECT statement using OPENXML rowset provider.
SELECT *
FROM OPENXML (@idoc, '/ROOT/Customer',3)
         WITH (CustomerID  varchar(10),
               ContactName varchar(20))

EXEC sp_xml_removedocument @idoc

下面是查询结果。

CustomerID ContactName
---------- --------------------
VINET      Paul Henriot
LILAS      Carlos Gonzlez

attribute-centric 映射应用于 CustomerID。在 <Customers> 元素内没有 ContactName 特性；因此，应用 element-centric 映射。

D. 指定 text() XPath 函数作为 ColPattern

下例中的 XML 文档由 <Customer> 和 <Order> 元素组成。OPENXML 语句从 <Order> 元素、节点的（rowpattern 所标识的）父节点 ID 和元素内容的叶值字符串中检索由 oid 特性组成的行集。

首先调用 sp_xml_preparedocument 以获得文档句柄。此文档句柄传递到 OPENXML。

在 OPENXML 语句中：

  • rowpattern (/root/Customer/Order) 标识要处理的 <Order> 节点。

  • flags 参数值设置为 1 表示 attribute-centric 映射。因此，XML 特性映射到 SchemaDeclaration 中定义的行集列。

  • 在 SchemaDeclaration 中（在 WITH 子句中），行集列名、oid 和 amount 与相应的 XML 特性名相匹配。因此，没有指定 ColPattern 参数。对于行集中的 comment 列，将 XPath 函数 (text()) 指定为 ColPattern。这将重写在 flags 参数中指定的 attribute-centric 映射，而且列将包含元素内容的叶值字符串。

SELECT 语句于是检索 OPENXML 所提供的行集中的所有列。

DECLARE @idoc int
DECLARE @doc varchar(1000)
--sample XML document
SET @doc ='
<root>
  <Customer cid= "C1" name="Janine" city="Issaquah">
      <Order oid="O1" date="1/20/1996" amount="3.5" />
      <Order oid="O2" date="4/30/1997" amount="13.4">Customer was very satisfied
      </Order>
   </Customer>
   <Customer cid="C2" name="Ursula" city="Oelde" >
      <Order oid="O3" date="7/14/1999" amount="100" note="Wrap it blue
             white red">
            <Urgency>Important</Urgency>
            Happy Customer.
      </Order>
      <Order oid="O4" date="1/20/1996" amount="10000"/>
   </Customer>
</root>
'
-- Create an internal representation of the XML document.
EXEC sp_xml_preparedocument @idoc OUTPUT, @doc

-- Execute a SELECT statement using OPENXML rowset provider.
SELECT *
FROM OPENXML (@idoc, '/root/Customer/Order', 1)
      WITH (oid     char(5),
            amount  float,
            comment ntext 'text()')
EXEC sp_xml_removedocument @idoc

结果如下：

oid   amount        comment
----- -----------   -----------------------------
O1    3.5           NULL
O2    13.4          Customer was very satisfied
O3    100.0         Happy Customer.
O4    10000.0       NULL
E. 在 WITH 子句中指定 TableName

下例在 WITH 子句中指定 TableName，而不在 WITH 子句中指定 SchemaDeclaration。这在表具有希望的结构且不需要列模式（ColPattern 参数）时很有用。

下例中的 XML 文档由 <Customer> 和 <Order> 元素组成。OPENXML 语句从 XML 文档中检索三列行集（oid、date 和 amount）中的订单信息。

首先调用 sp_xml_preparedocument 以获得文档句柄。此文档句柄传递到 OPENXML。

在 OPENXML 语句中：

  • rowpattern (/root/Customer/Order) 标识要处理的 <Order> 节点。

  • 在 WITH 子句中没有 SchemaDeclaration。相反，指定了一个表名。因此，表架构用作行集架构。

  • flags 参数值设置为 1 表示 attribute-centric 映射。因此，rowpattern 所标识的元素特性映射到具有相同名称的行集列。

SELECT 语句于是检索 OPENXML 所提供的行集中的所有列。

-- Create a test table. This table schema is used by OPENXML as the
-- rowset schema.
CREATE TABLE T1(oid char(5), date datetime, amount float)
DECLARE @idoc int
DECLARE @doc varchar(1000)
-- Sample XML document
SET @doc ='
<root>
  <Customer cid= "C1" name="Janine" city="Issaquah">
      <Order oid="O1" date="1/20/1996" amount="3.5" />
      <Order oid="O2" date="4/30/1997" amount="13.4">Customer was very
             satisfied</Order>
   </Customer>
   <Customer cid="C2" name="Ursula" city="Oelde" >
      <Order oid="O3" date="7/14/1999" amount="100" note="Wrap it blue
             white red">
          <Urgency>Important</Urgency>
      </Order>
      <Order oid="O4" date="1/20/1996" amount="10000"/>
   </Customer>
</root>
'
--Create an internal representation of the XML document.
EXEC sp_xml_preparedocument @idoc OUTPUT, @doc

-- Execute a SELECT statement using OPENXML rowset provider.
SELECT *
FROM OPENXML (@idoc, '/root/Customer/Order', 1)
      WITH T1
EXEC sp_xml_removedocument @idoc

结果如下：

oid   date                        amount
----- --------------------------- ----------
O1    1996-01-20 00:00:00.000     3.5
O2    1997-04-30 00:00:00.000     13.4
O3    1999-07-14 00:00:00.000     100.0
O4    1996-01-20 00:00:00.000     10000.0
F. 获得边缘表格式的结果

在下例中，在 OPENXML 语句中未指定 WITH 子句。因此，OPENXML 所生成的行集具有边缘表格式。SELECT 语句返回边缘表中的所有列。

下例中的示例 XML 文档由 <Customer>、<Order> 和 <OrderDetail> 元素组成。

首先调用 sp_xml_preparedocument 以获得文档句柄。此文档句柄传递到 OPENXML。

在 OPENXML 语句中：

  • rowpattern (/ROOT/Customer) 标识要处理的 <Customer> 节点。

  • 没有提供 WITH 子句，因此 OPENXML 返回边缘表格式的行集。

SELECT 语句于是检索边缘表中的所有列。

DECLARE @idoc int
DECLARE @doc varchar(1000)
SET @doc ='
<ROOT>
<Customer CustomerID="VINET" ContactName="Paul Henriot">
   <Order CustomerID="VINET" EmployeeID="5" OrderDate=
           "1996-07-04T00:00:00">
      <OrderDetail OrderID="10248" ProductID="11" Quantity="12"/>
      <OrderDetail OrderID="10248" ProductID="42" Quantity="10"/>
   </Order>
</Customer>
<Customer CustomerID="LILAS" ContactName="Carlos Gonzlez">
   <Order CustomerID="LILAS" EmployeeID="3" OrderDate=
           "1996-08-16T00:00:00">
      <OrderDetail OrderID="10283" ProductID="72" Quantity="3"/>
   </Order>
</Customer>
</ROOT>'
--Create an internal representation of the XML document.
EXEC sp_xml_preparedocument @idoc OUTPUT, @doc
-- Execute a SELECT statement using OPENXML rowset provider.
SELECT *
FROM OPENXML (@idoc, '/ROOT/Customer')
EXEC sp_xml_removedocument @idoc

结果作为边缘表返回。可以对边缘表编写查询以获得信息。

  • 下面的查询返回文档中的 Customer 节点数。因为未指定 WITH 子句，所以 OPENXML 返回边缘表。SELECT 语句查询此边缘表。
    SELECT count(*)
FROM OPENXML(@idoc, '/')
WHERE localname = 'Customer'
  • 下面的查询返回元素类型的 XML 节点的本地名称。
    SELECT distinct localname
FROM OPENXML(@idoc, '/')
WHERE nodetype = 1
ORDER BY localname
G. 指定以特性结束的 rowpattern

下例中的 XML 文档由 <Customer>、<Order> 和 <OrderDetail> 元素组成。OPENXML 语句从 XML 文档中检索三列行集（ProductIDProductID、Quantity 和 OrderID）中的订单详情。

首先调用 sp_xml_preparedocument 以获得文档句柄。此文档句柄传递到 OPENXML。

在 OPENXML 语句中：

  • rowpattern (/ROOT/Customer/Order/OrderDetail/@ProductID) 以 XML 特性 (ProductID) 结束。在所得到的行集中，为在 XML 文档中选定的每个特性节点都创建一行。

  • 在下例中未指定 flags 参数。相反，由 ColPattern 参数指定映射。

在 SchemaDeclaration（在 WITH 子句内）中，也用 ColName 和 ColType 参数指定 ColPattern。可选的 ColPattern 是指定的 XPath 模式，用以表示：

  • 在行集中为 ProdID 列指定的 ColPattern 的 XPath 模式 (.) 标识上下文节点（当前节点）。按照指定的 rowpattern，它是 <OrderDetail> 元素的 ProductID 特性。

  • 在行集中为 Qty 列指定的 ColPattern, ../@Quantity 标识上下文节点 (<ProductID>) 的父节点 (<OrderDetail>) 的 Quantity 特性。

  • 同样，在行集中为 OID 列指定的 ColPattern, ../../@OrderID 标识上下文节点 (<OrderDetail>) 的父节点 (<Order>) 的 OrderID 特性。

然后 SELECT 语句检索 OPENXML 所提供的行集中的所有列。

DECLARE @idoc int
DECLARE @doc varchar(1000)
--Sample XML document
SET @doc ='
<ROOT>
<Customer CustomerID="VINET" ContactName="Paul Henriot">
   <Order OrderID="10248" CustomerID="VINET" EmployeeID="5" OrderDate=
           "1996-07-04T00:00:00">
      <OrderDetail ProductID="11" Quantity="12"/>
      <OrderDetail ProductID="42" Quantity="10"/>
   </Order>
</Customer>
<Customer CustomerID="LILAS" ContactName="Carlos Gonzlez">
   <Order OrderID="10283" CustomerID="LILAS" EmployeeID="3" OrderDate=
           "1996-08-16T00:00:00">
      <OrderDetail ProductID="72" Quantity="3"/>
   </Order>
</Customer>
</ROOT>'
-- Create an internal representation of the XML document.
EXEC sp_xml_preparedocument @idoc OUTPUT, @doc
-- Execute a SELECT stmt using OPENXML rowset provider.
SELECT *
FROM OPENXML (@idoc, '/ROOT/Customer/Order/OrderDetail/@ProductID')
       WITH ( ProdID  int '.',
              Qty     int '../@Quantity',
              OID     int '../../@OrderID')
EXEC sp_xml_removedocument @idoc

结果如下：

ProdID      Qty         OID
----------- ----------- -------
11          12          10248
42          10          10248
72          3           10283
H. 指定有多个文本节点的 XML 文档

如果在 XML 文档中有多个文本节点，则含有 ColPattern (text()) 的 SELECT 语句只返回第一个文本节点，而不是返回所有节点。例如：

DECLARE @h int
EXEC sp_xml_preparedocument @h OUTPUT,
         N'
         <root xmlns:a="urn:1">
           <a:Elem abar="asdf">
             T<a>a</a>U
           </a:Elem>
         </root>',
         '<ns xmlns:b="urn:1" />'

SELECT * FROM openxml(@h, '/root/b:Elem')
      WITH (Col1 varchar(20) 'text()')

SELECT 语句返回 T 作为结果（不是 TaU）。

I. 从多值特性中检索单值

XML 文档会含有多值特性。例如 IDREFS 可为多值特性。在 XML 文档内，多值特性值被指定为由用空格隔开的值组成的字符串。在下列 XML 文档内，<Student> 元素的 attends 特性与 <Class> 的 attendedBy 特性都是多值特性。从多值 XML 属性中检索单值并将每个值存储到数据库中的不同行中，这要求额外的工作。下例显示了此过程。

该 XML 示例文档由以下元素组成：

  • <Student>

    包括 id（学生 ID）、name 和 attends 特性。该 attends 特性是多值特性。

  • <Class>

    包括 id（班级 ID）、name 和 attendedBy 特性。该 attendedBy 特性是多值特性。

<Student> 内的 attends 特性和 <Class> 内的 attendedBy 特性表示 Student 表与 Class 表之间的一种 m:n 关系。一个学生可在很多班上课，而一个班也可有很多学生。

假设希望拆分该文档，并将它以下列形式保存到数据库中：

  • 将 <Student> 数据保存到 Students 表中。

  • 将 <Class> 数据保存到 Courses 表中。

  • 将 m:n 关系数据（在 Student 与 Class之间）保存到 CourseAttendence 表中。析取这些值需要做额外的工作。若要检索该信息并将其存储到表中，请使用下列存储过程：
    • Insert_Idrefs_Values

      将课程 ID 和学生 ID 的值插入 CourseAttendence 表中。

    • Extract_idrefs_values

      从每个 <Course> 元素中析取单个学生 ID。用边缘表检索这些值。

以下是具体步骤：

  1. 创建下表：
    DROP TABLE CourseAttendance
DROP TABLE Students
DROP TABLE Courses
GO
CREATE TABLE Students(
                id   varchar(5) primary key,
                name varchar(30)
                )
GO
CREATE TABLE Courses(
               id       varchar(5) primary key,
               name     varchar(30),
               taughtBy varchar(5)
)
GO
CREATE TABLE CourseAttendance(
             id         varchar(5) references Courses(id),
             attendedBy varchar(5) references Students(id),
             constraint CourseAttendance_PK primary key (id, attendedBy)
)
go
  2. 创建下列存储过程：
    DROP PROCEDURE f_idrefs
GO
CREATE PROCEDURE f_idrefs
    @t      varchar(500),
    @idtab  varchar(50),
    @id     varchar(5)
AS
DECLARE @sp int
DECLARE @att varchar(5)
SET @sp = 0
WHILE (LEN(@t) > 0)
BEGIN
    SET @sp = CHARINDEX(' ', @t+ ' ')
    SET @att = LEFT(@t, @sp-1)
    EXEC('INSERT INTO '+@idtab+' VALUES ('''+@id+''', '''+@att+''')')
    SET @t = SUBSTRING(@t+ ' ', @sp+1, LEN(@t)+1-@sp)
END
Go

DROP PROCEDURE fill_idrefs
GO
CREATE PROCEDURE fill_idrefs
    @xmldoc     int,
    @xpath      varchar(100),
    @from       varchar(50),
    @to         varchar(50),
    @idtable    varchar(100)
AS
DECLARE @t varchar(500)
DECLARE @id varchar(5)

/* Temporary Edge table */
SELECT *
INTO #TempEdge
FROM OPENXML(@xmldoc, @xpath)

DECLARE fillidrefs_cursor CURSOR FOR
    SELECT CAST(iv.text AS nvarchar(200)) AS id,
           CAST(av.text AS nvarchar(4000)) AS refs
    FROM   #TempEdge c, #TempEdge i,
           #TempEdge iv, #TempEdge a, #TempEdge av
    WHERE  c.id = i.parentid
    AND    UPPER(i.localname) = UPPER(@from)
    AND    i.id = iv.parentid
    AND    c.id = a.parentid
    AND    UPPER(a.localname) = UPPER(@to)
    AND    a.id = av.parentid

OPEN fillidrefs_cursor
FETCH NEXT FROM fillidrefs_cursor INTO @id, @t
WHILE (@@FETCH_STATUS <> -1)
BEGIN
    IF (@@FETCH_STATUS <> -2)
    BEGIN
        execute f_idrefs @t, @idtable, @id
    END
    FETCH NEXT FROM fillidrefs_cursor INTO @id, @t
END
CLOSE fillidrefs_cursor
DEALLOCATE fillidrefs_cursor
Go
  3. 这是已拆分的示例文档，已将数据存储到前面提到的表中。
    DECLARE @h int
EXECUTE sp_xml_preparedocument @h OUTPUT, '
<Data>
  <Student id = "s1" name = "Student1"  attends = "c1 c3 c6"  />
  <Student id = "s2" name = "Student2"  attends = "c2 c4" />
  <Student id = "s3" name = "Student3"  attends = "c2 c4 c6" />
  <Student id = "s4" name = "Student4"  attends = "c1 c3 c5" />
  <Student id = "s5" name = "Student5"  attends = "c1 c3 c5 c6" />
  <Student id = "s6" name = "Student6" />

  <Class id = "c1" name = "Intro to Programming"
         attendedBy = "s1 s4 s5" />
  <Class id = "c2" name = "Databases"
         attendedBy = "s2 s3" />
  <Class id = "c3" name = "Operating Systems"
         attendedBy = "s1 s4 s5" />
  <Class id = "c4" name = "Networks" attendedBy = "s2 s3" />
  <Class id = "c5" name = "Algorithms and Graphs"
         attendedBy =  "s4 s5"/>
  <Class id = "c6" name = "Power and Pragmatism"
         attendedBy = "s1 s3 s5" />
</Data>'

INSERT INTO Students SELECT * FROM OPENXML(@h, '//Student') WITH Students

INSERT INTO Courses SELECT * FROM OPENXML(@h, '//Class') WITH Courses
/* Using the edge table */
EXECUTE fill_idrefs @h, '//Class', 'id', 'attendedby', 'CourseAttendance'

SELECT * FROM Students
SELECT * FROM Courses
SELECT * FROM CourseAttendance

EXECUTE sp_xml_removedocument @h

请参见

sp_xml_preparedocument

sp_xml_removedocument

OPENXML

使用 OPENXML 编写 XML


在 OPENXML 中指定元属性

XML 文档中的元属性特性用于描述 XML 项目（元素、特性或任何其它 DOM 节点）的属性。这些特性并不实际存在于 XML 文档文本中，但 OPENXML 可为所有 XML 项目提供这些元属性。这些元属性使您得以析取 XML 节点的信息（如本地定位、命名空间信息），以提供比文本化表示法更详细的信息。

在 OPENXML 语句中使用 ColPattern 参数，可将这些元属性映射到行集列。这些列将包含映射到的元属性的值。有关 OPENXML 语法的更多信息，请参见 OPENXML。

若要访问元属性特性，应提供 Microsoft® SQL Server™ 2000 特有的命名空间 (urn:schemas-microsoft-com:xml-metaprop)。如果 OPENXML 查询结果以边缘表格式返回，则每个元属性特性在边缘表中都有一列（xmltext 元属性除外）。

有些元属性用于处理目的。例如，xmltext 元属性特性用于溢出处理。溢出处理针对文档中未用完/未处理的数据。可以通过使用 ColPattern 参数，将 OPENXML 生成的行集中的某列映射到 xmltext 元属性，以将该列标识为溢出列。该列于是将接收溢出数据（flags 参数确定该列是只包含未用完的数据还是包含任何数据）。

下表列出每个经过分析的 XML 元素所具有的元属性特性。可以使用命名空间 urn:schemas-microsoft-com:xml-metaprop访问这些元属性特性。用户使用这些元属性在 XML 文档中直接设置的任何值均被忽略。

说明 不能在任何 XPath 导航中引用这些元属性。

元属性特性 | 描述
@mp:id | 提供由系统生成的、文档范围的 DOM 节点（元素、特性等）标识符。只要文档未被重新分析，就能保证此 ID 引用同一个 XML 节点。 XML ID 为 0 表示元素是根元素。其父 XML ID 为 NULL。
@mp:localname | 存储节点名的本地部分。与前缀及命名空间 URI（统一资源标识符）一起用于命名元素或特性节点。
@mp:namespaceuri | 提供当前元素的命名空间。如果该特性值为 NULL，则表明不存在命名空间。
@mp:prefix | 存储当前元素名的命名空间前缀。 如果前缀不存在（为 NULL）且给定了 URI，则表示指定的命名空间为默认命名空间。如果没有给定 URI，则不附加命名空间。
@mp:prev | 存储相对于节点的前一个兄弟元素，因此可提供有关文档中的元素排列信息。 @mp:prev 包含具有相同父元素的前一个兄弟元素的 XML ID。如果某个元素位于兄弟元素列表的开头，则 @mp:prev 为 NULL。
@mp:xmltext | 此元属性用于处理目的。是由元素及其特性以及 OPENXML 溢出处理中使用的子元素组成的文本串。

下表显示使您得以检索层次结构信息的其它父属性。

父元属性特性 | 描述
@mp:parentid | 相当于 ../@mp:id
@mp:parentlocalname | 相当于 ../@mp:localname
@mp:parentnamespacerui | 相当于 ../@mp:namespaceuri
@mp:parentprefix | 相当于 ../@mp:prefix

示例
A. 将 OPENXML 行集列映射到元属性

下例通过使用 OPENXML 创建示例 XML 文档的行集视图。下例说明如何在 OPENXML 语句中使用 ColPattern 参数将各种元属性特性映射到行集列。

在 OPENXML 语句中：

  • 将 id 列映射到 @mp:id 元属性特性，表示此列包含系统生成的该元素的唯一 XML ID。

  • 将 parent 列映射到 @mp:parentid，表示此列包含该元素的父元素 XML ID。

  • 将 parentLocalName 列映射到 @mp:parentlocalname，表示此列包含父元素的本地名。

然后 SELECT 语句返回由 OPENXML 提供的行集。

DECLARE @idoc int
DECLARE @doc varchar(1000)
-- Sample XML document
SET @doc ='
<root>
  <Customer cid= "C1" name="Janine" city="Issaquah">
      <Order oid="O1" date="1/20/1996" amount="3.5" />
      <Order oid="O2" date="4/30/1997" amount="13.4">Customer was very satisfied</Order>
   </Customer>
   <Customer cid="C2" name="Ursula" city="Oelde" >
      <Order oid="O3" date="7/14/1999" amount="100" note="Wrap it blue white red">
          <Urgency>Important</Urgency>
      </Order>
      <Order oid="O4" date="1/20/1996" amount="10000"/>
   </Customer>
</root>
'
-- Create an internal representation of the XML document.
EXEC sp_xml_preparedocument @idoc OUTPUT, @doc

-- Execute a SELECT statement using OPENXML rowset provider.
SELECT *
FROM OPENXML (@idoc, '/root/Customer/Order', 9)
      WITH (id int '@mp:id',
            oid char(5),
            date datetime,
            amount real,
            parentIDNo int '@mp:parentid',
            parentLocalName varchar(40) '@mp:parentlocalname')
EXEC sp_xml_removedocument @idoc

结果如下：

id   oid         date                amount    parentIDNo  parentLocalName
--- ------- ---------------------- ---------- ------------ ---------------
6    O1    1996-01-20 00:00:00.000     3.5         2        Customer
10   O2    1997-04-30 00:00:00.000     13.4        2        Customer
19   O3    1999-07-14 00:00:00.000     100.0       15       Customer
25   O4    1996-01-20 00:00:00.000     10000.0     15       Customer
B. 检索整个 XML 文档

在下例中，OPENXML 创建示例 XML 文档的一个列行集视图。此列 (Col1) 映射到 xmltext 元属性，从而成为一个溢出列。因此此列将接收未用完的数据，在本例中未用完的数据指整个文档。

最后 SELECT 语句返回整个行集。

DECLARE @idoc int
DECLARE @doc varchar(1000)
SET @doc ='
<?xml version="1.0"?>
<root>
  <Customer cid= "C1" name="Janine" city="Issaquah">
      <Order oid="O1" date="1/20/1996" amount="3.5" />
      <Order oid="O2" date="4/30/1997" amount="13.4">Customer was very
             satisfied</Order>
   </Customer>
   <Customer cid="C2" name="Ursula" city="Oelde" >
      <Order oid="O3" date="7/14/1999" amount="100" note="Wrap it blue
             white red">
     <MyTag>Testing to see if all the subelements are returned</MyTag>
          <Urgency>Important</Urgency>
      </Order>
      <Order oid="O4" date="1/20/1996" amount="10000"/>
   </Customer>
</root>
'
-- Create an internal representation of the XML document.
EXEC sp_xml_preparedocument @idoc OUTPUT, @doc

-- Execute a SELECT statement using OPENXML rowset provider.
SELECT *
FROM OPENXML (@idoc, '/')
   WITH (Col1 ntext '@mp:xmltext')

若要在不声明 XML 的情况下检索整个文档，可将查询指定为：

SELECT *
FROM OPENXML (@idoc, '/root')
   WITH (Col1 ntext '@mp:xmltext')
EXEC sp_xml_removedocument @idoc

查询返回带有名称根的根元素以及根元素包含的数据。

C. 指定 xmltext 元属性检索列中未用完的数据

下例通过使用 OPENXML 创建示例 XML 文档的行集视图。下例说明如何将 xmltext 元属性特性映射到 OPENXML 中的某个行集列以检索未用完的 XML 数据。

将注释列映射到 @mp:xmltext 元属性以将其标识为溢出列。参数 flags 设置为 9（XML_ATTRIBUTE 和 XML_NOCOPY），表示 attribute-centric 映射，且只能将未用完的数据复制到溢出列。

然后 SELECT 语句返回由 OPENXML 提供的行集。

在下例中，为 OPENXML 所生成的行集中的一列 (ParentLocalName) 设置 @mp:parentlocalname 元属性。结果，此列包含父元素的本地名。

在行集中另外指定两列（parent 和 comment）。将 parent 列映射到 @mp:parentid，表示此列包含该元素的父元素 XML ID。将注释列映射到 @mp:xmltext 元属性以将其标识为溢出列。

DECLARE @idoc int
DECLARE @doc varchar(1000)
-- sample XML document
SET @doc ='
<root>
  <Customer cid= "C1" name="Janine" city="Issaquah">
      <Order oid="O1" date="1/20/1996" amount="3.5" />
      <Order oid="O2" date="4/30/1997" amount="13.4">Customer was very satisfied</Order>
   </Customer>
   <Customer cid="C2" name="Ursula" city="Oelde" >
      <Order oid="O3" date="7/14/1999" amount="100" note="Wrap it blue white red">
          <Urgency>Important</Urgency>
      </Order>
      <Order oid="O4" date="1/20/1996" amount="10000"/>
   </Customer>
</root>
'
-- Create an internal representation of the XML document.
EXEC sp_xml_preparedocument @idoc OUTPUT, @doc

-- Execute a SELECT statement using OPENXML rowset provider.
SELECT *
FROM OPENXML (@idoc, '/root/Customer/Order', 9)
      WITH (oid char(5),
            date datetime,
            comment ntext '@mp:xmltext')
EXEC sp_xml_removedocument @idoc

结果如下。因为用完了 oid 和 date 列，因此它们不出现在溢出列中。

oid   date                        comment
----- --------------------------- ----------------------------------------
O1    1996-01-20 00:00:00.000     <Order amount="3.5"/>
O2    1997-04-30 00:00:00.000     <Order amount="13.4">Customer was very
                                   satisfied</Order>
O3    1999-07-14 00:00:00.000     <Order amount="100" note="Wrap it blue
                                   white red"><Urgency>
                                   Important</Urgency></Order>
O4    1996-01-20 00:00:00.000     <Order amount="10000"/>

请参见

使用 OPENXML 编写 XML

OPENXML


XML 系统存储过程

Microsoft® SQL Server™ 2000 提供下列与 OPENXML 一同使用的系统存储过程：

  • sp_xml_preparedocument

  • sp_xml_removedocument

若要使用 OPENXML 编写查询，必须先通过调用 sp_xml_preparedocument 创建 XML 文档的内部表示法。该存储过程返回 XML 文档的内部表示法的句柄。该句柄随后传递给 OPENXML，后者基于 XPath 提供此文档的行集视图，即单行模式和单列或多列模式。

通过调用 sp_xml_removedocument 系统存储过程可将 XML 文档的内部表示法从内存中删除。

请参见

OPENXML


示例 XML 应用程序

本部分的主题将展示简单的应用程序，说明如何将 XML 文档从客户端传递到服务器。然后用 OPENXML 拆分 XML 文档，并对数据库中的表做必要的更新。


使用 OPENXML 插入记录的示例 HTML 表单

下面的示例 HTML 表单提示用户输入职员 ID、名和姓。用户在表单中输入以上数据后，将创建包含要插入数据库的职员元素的 XML 文档。此 XML 文档作为参数传递给模板。

执行下例前，必须创建一个虚拟根。有关更多信息，请参见创建 nwind 虚拟目录。

下例显示：

  • 如何创建简单的 HTML 表单。

  • 如何从输入 HTML 表单中的数据创建 XML 文档。

  • 如何将 XML 文档传递给模板。

  • 如何在 INSERT 语句中使用 OPENXML 子句将记录添加到数据库中。

该模板执行一个存储过程。XML 文档作为文本参数传递给该存储过程。

该存储过程：

  • 调用 sp_xml_preparedocument 创建以文本参数形式传递的 XML 文档的内部表示法。

  • 调用 INSERT 语句在 Employee 表中插入职员记录。要插入的记录由 OPENXML 提供，而 OPENXML 创建 XML 文档的行集视图。

创建工作示例包含以下几步：

  1. 创建下表：
    CREATE TABLE Employee(eid int, fname varchar(20), lname varchar(20))
  2. 在数据库中创建下面的存储过程：
    CREATE PROC sp_insert_employee @empdata ntext
AS
       DECLARE @hDoc int
    EXEC sp_xml_preparedocument @hDoc OUTPUT, @empdata
    INSERT INTO Employee
      SELECT *
      FROM OPENXML(@hDoc, '/Employee')
            WITH Employee
     EXEC sp_xml_removedocument @hDoc
  3. 创建下面的模板。该模板必须存储在与模板类型的虚拟名称相关的目录中（如果已经创建了示例 nwind 虚拟目录，则将模板存放在此虚拟根目录的模板子目录中）。将此模板另存为 MyTemplate.xml。
    <root xmlns:sql="urn:schemas-microsoft-com:xml-sql">
<sql:header>
<sql:param name="empdata"><Employee/></sql:param>
</sql:header>
<sql:query>exec sp_insert_employee @empdata
</sql:query>
</root>

下面是 HTML 表单：

<html>
<body>
  <form action="http://IISServer/nwind/template
            /MyTemplate.xml" method="post">
    <input type="hidden" id="e" name="empdata">
    <input type="hidden" name="contenttype" value="text/xml">
       EmployeeID: <input type=text id=eid value="1"><br>
       First Name: <input type=text id=fname value="Harry"><br>
       Last Name: <input type=text id=lname value="Smith"><br>
     <input type=submit onclick="Insert_Employee(e, eid,
       lname, fname)" value="Insert Employee"><br><br>

<script>
    function Insert_Employee(e, eid, lname, fname)
     {
      e.value = '<Employee eid="' + eid.value +
      '" lname="' + lname.value + '" fname="' +
      fname.value + '"/>';
     }
</script>
</form>
</body>
</html>


使用 OPENXML 更新记录的示例 HTML 表单

该示例应用程序显示如何用 XML 文档内的数据更新数据库表中的记录。该应用程序显示以下过程：

  • 从 HTML 表单执行模板。

  • 将 XML 文档作为参数传递给模板。

  • 在模板中执行 SQL 语句（存储过程）。

  • 使用带 UPDATE 的 OPENXML 行集提供程序应用更新。

该应用程序假设客户端已有用其它应用程序创建的 XML 文档。该应用程序用 OPENXML 拆分 XML 文档并创建传递给 UPDATE 语句的行集。

执行下例前，必须创建一个虚拟根。有关更多信息，请参见创建 nwind 虚拟目录。

模板执行存储过程 (sp_update_employee)。XML 文档作为文本参数传递给该存储过程。

该存储过程：

  • 调用 sp_xml_preparedocument 创建以文本参数形式传递的 XML 文档的内部表示法。

  • 调用 UPDATE 语句更新 Employee 表中的职员记录。OPENXML 提供 XML 的行集视图，该视图用于 UPDATE 语句。

创建工作示例包含以下几步：

  1. 创建下表：
    CREATE TABLE Employee(eid int, fname varchar(20), lname varchar(20))
  2. 添加示例数据：
    INSERT INTO Employee VALUES (1, 'Nancy', 'Davolio')
INSERT INTO Employee VALUES (2, 'Andrew', 'Fuller')
  3. 在数据库中创建下面的存储过程：
    CREATE PROC sp_update_employee @empdata ntext
AS
DECLARE @hDoc int
exec sp_xml_preparedocument @hDoc OUTPUT,@empdata
UPDATE Employee
SET
      Employee.fname = XMLEmployee.fname,
      Employee.lname = XMLEmployee.lname
FROM OPENXML(@hDoc, '/root/Employee')
             WITH Employee XMLEmployee
WHERE  Employee.eid = XMLEmployee.eid
EXEC sp_xml_removedocument @hDoc
SELECT   *
from      Employee
FOR XML AUTO
  4. 创建下面的模板。该模板必须存储在与模板类型的虚拟名称相关的目录中（如果已经创建了示例 nwind 虚拟目录，则将模板存放在此虚拟根目录的模板子目录中）。将模板保存为 UpdateEmployee.xml。
    <root xmlns:sql="urn:schemas-microsoft-com:xml-sql">
    <sql:header>
        <sql:param name="empdata"><Employee/></sql:param>
    </sql:header>
    <sql:query>
         exec sp_update_employee @empdata
    </sql:query>
</root>

下面是 HTML 表单：

<html>
<body>
<form name="Employee"
      action="http://localhost/nwind/Template/UpdateEmployee.XML"
      method="POST">
This app assumes that client has this simple
XML document created using some other application and you want to
update the tables based on the data in this document.<br>
---------------------------------------<br>
<input type=hidden name="contenttype" value="text/xml">
<textarea name="empdata" cols=50 rows=5>
   &lt;root&gt;
     &lt;Employee eid=&quot;1&quot; lname=&quot;Leverling&quot; fname=&quot;Janet&quot;/&gt;
     &lt;Employee eid=&quot;2&quot; lname=&quot;Peacock&quot; fname=&quot;Margaret&quot;/&gt;
   &lt;/root&gt;
</textarea>
<br><input type=Submit value="Submit">
</form>
</body>
</html>

请参见

用于 SQL Server 的 IIS 虚拟目录管理

使用 HTTP 执行模板文件

使用 XPath 查询


使用 OPENXML 和 ADO 更新记录的示例 Visual Basic 应用程序

该应用程序基于客户端已有 XML 文档（用某些其它应用程序创建）的假设，并且该文档用以将更新应用到数据库。

下例显示：

  • 编写一个简单的 Microsoft® Visual Basic® 应用程序以更新使用 XML 文档的数据库。

  • 用 ADO 执行 XML 模板。

  • 创建及执行模板，并将参数传递给模板。

  • 用 OPENXML 从 XML 文档中创建一个行集。

创建工作示例包含以下几步：

  1. 创建下表：
    CREATE TABLE Employee(eid int, fname varchar(20), lname varchar(20))
  2. 添加示例数据：
    INSERT INTO Employee VALUES (1, 'Nancy', 'Davolio')
INSERT INTO Employee VALUES (2, 'Andrew', 'Fuller')
  3. 在数据库中创建下面的存储过程：
    CREATE PROC update_employee @empdata nvarchar(4000)
AS
 DECLARE @hDoc int
 exec sp_xml_preparedocument @hDoc OUTPUT,@empdata
 UPDATE Employee
 SET
   Employee.fname = XMLEmployee.fname,
   Employee.lname = XMLEmployee.lname
 FROM OPENXML(@hDoc, 'update/Employee')
       WITH Employee XMLEmployee
 WHERE  Employee.eid = XMLEmployee.eid
 EXEC sp_xml_removedocument @hDoc
  4. 创建 Visual Basic 项目（一个标准的 EXE 项目就足够了）。

  5. 将 Microsoft ActiveX® Data Objects 2.6 Library 添加到项目引用中。

  6. 添加下列代码：
    'The code uses ADO to establish a SQL Server connection and passes in a
'template to the server. The template executes a stored procedure
'(update_employee) which accepts an XML document as input. The stored
'procedure uses OPENXML to shred the document and generate a rowset
'which is used to update the records in the Employee table.
'The template is then executed on the server and the resulting stream
'is returned to the client. The stream contains the resulting XML
'document.

Dim cmd As New ADODB.Command
Dim conn As New ADODB.Connection
Dim strmIn As New ADODB.Stream
Dim strmOut As New ADODB.Stream

' Open a connection to the SQL Server.
conn.Provider = "SQLOLEDB"
conn.Open "server=(local); database=Northwind; uid=sa; "

Set cmd.ActiveConnection = conn

' Build the command string in the form of an XML template.
SQLxml = "<root xmlns:sql=""urn:schemas-microsoft-com:xml-sql""><sql:query><![CDATA["
SQLxml = SQLxml & "exec update_employee N'<update><Employee eid=""1"" lname=""Leverling"" fname=""Janet""/>"
SQLxml = SQLxml & "<Employee eid=""2"" lname=""Peacock"" fname=""Margaret""/></update>']]>"
SQLxml = SQLxml & "</sql:query></root>"

' Set the command dialect to XML.
cmd.Dialect = "{5d531cb2-e6ed-11d2-b252-00c04f681b71}"

' Open the command stream and write our template to it.
strmIn.Open
strmIn.WriteText SQLxml
strmIn.Position = 0

Set cmd.CommandStream = strmIn

' Execute the command, open the return stream, and read the result.
strmOut.Open
strmOut.LineSeparator = adCRLF
cmd.Properties("Output Stream").Value = strmOut
cmd.Execute , , adExecuteStream
strmOut.Position = 0
Debug.Print strmOut.ReadText


用于 XML 的 SQL Server OLE DB 提供程序扩展

用于 SQL Server 的 Microsoft® OLE DB 提供程序 (SQLOLEDB) 支持一种称为 DBGUID_MSSQLXML 的新方言，用以在嵌入式查询（如 SQL FOR XML 和 XPath 查询）中执行 XML 模板。模板是包含一个或多个查询的有效的 XML 文档。FOR XML 和 XPath 查询返回文档片段。模板相当于所得到的文档片段的容器。

使用 ICommandText 设置 XML 命令

ICommandText::SetCommandText 和 ICommand::Execute 方法已增强，允许将 XML 文档设置为命令文本，并允许执行命令并检索流形式的结果，该结果可用于进一步的处理中，例如将 XML 文档传递到 DOM（文档对象模型）。

可以将 XML 模板传递到 ICommandText::SetCommandText 方法。当使用 ICommandText::SetCommandText 将 XML 设置为命令文本时，使用者必须将 DBGUID_MSSQLXML 作为命令语法的 GUID 传递。此新的 GUID 表示命令文本是一个 XML 模板。

使用者必须调用 ICommand::Execute 执行 XML 模板。若要获得 XML 文档格式的结果集，应将 riid 设置为 Istream，这样提供程序会将结果集作为流返回。

IcommandText 的限制

传递给 ICommandText::SetCommandText 的模板可以很大。如果执行的模板存储在文件中，则需要一定的开销读取文件、缓冲文件内容，然后使用 ICommandText::SetCommandText 设置命令文本。

另外，ICommandText::SetCommandText 接受的命令字符串为 Unicode 字符串。如果实际的 XML 文件使用了某种编码格式，则将该文件作为命令传递到 IcommandText::SetCommandText 之前，还需额外的开销将其转换为 Unicode。

使用 ICommandStream 设置 XML 命令

OLE DB（2.6 版）接口 IcommandStream 虽然与 IcommandText 类似，但仍将命令作为流对象而不是字符串进行传递。

SQLOLEDB 已在命令对象上实现了可选的 ICommandStream 接口。ICommandStream 接口使您得以将流传递到命令对象。

ICommandStream 接口允许命令采用 XML 分析器理解的任何编码方式。因而，当调用 ICommand::Execute 时，直接从流中读取命令文本而无需任何转换。使用 ICommandStream 接口执行 XML 命令将更有效。

SQLOLEDB 中实现了 ICommandStream::GetCommandStream 和 ICommandStream::SetCommandStream 接口。

对于 IcommandStream，默认方言 (DBGUID_DEFAULT) 为 DBGUID_MSSQLXML。ICommandStream::SetCommandStream 所支持的方言是提供程序特有的。SQLOLEDB 只支持 DBGUID_MSSSQLXML（不支持 DBGUID_SQL 和 DBGUID_XPATH）。

如果在调用 EXECUTE 前从 GetCommandStream 返回的流中读取，EXECUTE 可能会失败，除非 EXECUTE 能从流中的适当位置读取。

支持 OLE DB（2.6 版）DBPROPSET_STREAM 属性集

SQLOLEDB 已实现了 DBPROPSET_STREAM 属性集（在 Stream 属性组中），该属性集包括以下属性：

DBPROP_OUTPUTSTREAM

在该属性中传递的值是一个含有指向 IStream 或 IsequentialStream 的指针的变量。设置该属性后，ICommand::Execute 以该属性所指定的流形式返回结果。这样，因为可将流传递给其他用户（如 XML 分析器），所以可避免额外复制数据。

DBPROP_OUTPUTENCODING

该属性指定为 Execute 方法所返回的流请求的编码。常用的一些编码包括 UTF-8、ANSI 和 Unicode。如果该属性的值为 NULL，则默认编码为 UTF-8。

在 ICommand::Execute 上请求 ISequentialStream

可在 ICommand::Execute 上请求 IsequentialStream。

当从只要有数据可读的流中读取时，ISequentialStream::Read 返回 S_OK。在到达流的末端时，后续读取将返回 S_FALSE，除非在执行命令的过程中发生错误。如果有错误，在到达流的末端后只在第一次读取时返回 DB_S_ERRORSOCCURED。所有后续读取都将返回 S_FALSE。

在执行命令过程中，如果发生错误，错误会作为流中的处理说明 (PI) 返回。在最后一次读取后将返回所有错误。不能访问错误对象的应用程序可检查流内容中包含错误的 PI。

仅当选定的结果是单列行集时，才支持 IsequentialStream。

SQLOLEDB 提供程序特有的属性

为支持 XML 特有的行为，SQLOLEDB 在 DBPROPSET_SQLSERVERSTREAM 属性集（Stream 属性组）中实现了下列提供程序特有的属性。这些属性使您得以指定映射架构，并根据该架构将 XPath 查询指定为命令，或者使您得以指定 XSL 文件以处理结果。这些属性中的一部分有益于增强安全与性能。

SSPROP_STREAM_BASEPATH

该属性用于指定基本路径。基本路径用于解析为 XSL 文件、映射架构或模板中的外部架构引用指定的相对路径。

SSPROP_STREAM_MAPPINGSCHEMA

该属性用于指定 XPath 查询的架构。指定的路径可以是相对路径，也可以是绝对路径。如果指定的是相对路径，则 SSPROP_STREAM_BASEPATH 中指定的基本路径用于解析相对路径。如果未指定基本路径，则相对路径相对于当前目录。

SSPROP_STREAM_XSL

该属性用于指定 XSL 文件。指定的路径可以是相对路径，也可以是绝对路径。如果指定的是相对路径，则 SSPROP_STREAM_BASEPATH 中指定的基本路径用于解析相对路径。如果未指定基本路径，则相对路径相对于当前目录。

SSPROP_STREAM_CONTENTTYPE

如果对结果应用 XSL 样式表，则 XSL 文件中的 <xsl:output> 上的媒体类型属性作为该属性的值返回。

SSPROP_STREAM_FLAGS

该属性用于指定某些安全限制。例如，可能不希望对文件或文件的绝对路径（如外部站点）使用 URL 引用。可能不希望在模板中使用查询。可对该属性赋以如下值：STREAM_FLAGS_DISALLOW_URL、STREAM_FLAGS_DISALLOW_ABSOLUTE_PATH 或 STREAM_FLAGS_DISALLOW_QUERY。

有关这些属性的更多信息，请参见初始化和授权属性。


使用 ICommandStream 设置 XML 命令

OLE DB（2.6 版）接口 ICommandStream 将命令作为流对象而不是字符串进行传递。

该接口允许命令采用 XML 分析器理解的任何编码方式。当调用 ICommand::Execute 时，直接从流中读取命令文本而无需任何转换。因此，使用 ICommandStream 接口执行 XML 命令更有效。

使用 IcommandStream 将 XML 设置为命令并检索作为 XML 文档的结果

OLE DB