创建 XML 数据的实例

本主题说明了如何生成 XML 实例。

在 SQL Server 中,可以按照下列方式生成 XML 实例:

  • 对字符串实例进行类型转换。

  • 将 SELECT 语句与 FOR XML 子句结合使用。

  • 使用常量赋值。

  • 使用大容量加载。

类型转换字符串实例和二进制实例

您可以将任何 SQL Server 字符串数据类型(如 [n][var]char[n]textvarbinaryimage)分析成 xml 数据类型,方法是将相应字符串以 CAST 或 CONVERT 方式转换成 xml 数据类型。 对非类型化的 XML 进行检查以确认其格式是否正确。 如果存在与 xml 类型关联的架构,也会执行验证。 有关详细信息,请参阅类型化的 XML 与非类型化的 XML 的比较

XML 文档可以采用不同的编码方式(例如,UTF-8、UTF-16 和 windows-1252)进行编码。 下面概述了有关字符串和二进制源类型与 XML 文档编码进行交互的方式以及分析器行为方式的规则。

由于 nvarchar 采用为双字节 Unicode 编码(例如 UTF-16 或 UCS-2),因此 XML 分析器会将字符串值作为双字节 Unicode 编码 XML 文档或片断来处理。 这意味着该 XML 文档需要以双字节 Unicode 编码方式进行编码,同时需要与源数据类型兼容。 UTF-16 编码 XML 文档可以具有 UTF-16 字节顺序标记 (BOM),但是它不需要,因为源类型的上下文显式指出 UTF-16 编码 XML 文档只能是双字节 Unicode 编码文档。

varchar 字符串的内容被 XML 分析器视为单字节编码 XML 文档/片断。 由于 varchar 源字符串具有相关联的代码页,因此如果 XML 本身没有明确指定编码方式,分析器将使用该代码页。如果 XML 实例具有 BOM 或编码声明,则该 BOM 或声明应当与代码页一致,否则分析器将会报告一个错误。

varbinary 的内容被视为码位流,它将直接被传递到 XML 分析器。 这样,XML 文档或片断就需要提供 BOM 或其他内联编码信息。 分析器将仅查看该流来确定编码方式。 这意味着 UTF-16 编码 XML 需要提供 UTF-16 BOM,不带 BOM 和编码声明的实例将被解释为 UTF-8。

如果事先不知道 XML 文档的编码方式,并且数据在转换到 XML 之前被作为字符串或二进制数据而不是 XML 数据来传递,则建议将数据作为 varbinary 处理。 例如,当使用 OpenRowset() 从 XML 文件读取数据时,应该指定将数据作为 varbinary(max) 值读取:

select CAST(x as XML) 
from OpenRowset(BULK 'filename.xml', SINGLE_BLOB) R(x)

SQL Server 在内部以一种使用 UTF-16 编码的有效二进制表示形式来表示 XML。 用户提供的编码不会保留下来,但在分析过程中会考虑。

类型转换 CLR 用户定义类型

如果 CLR 用户定义类型具有 XML 序列化,则该类型的实例可以显式转换为 XML 数据类型。 有关 CLR 用户定义类型的 XML 序列化的详细信息,请参阅 从 CLR 数据库对象进行 XML 序列化

类型化的 XML 中的空格处理

在 SQL Server 中,如果元素内容中的空格出现在一组只有空格并由标记(如开始或结束标记)分隔的字符数据中,则认为其无关紧要,因此不对其进行实体化。 (忽略 CDATA 部分。)这种空格处理方式与万维网联盟 (W3C) 发布的 XML 1.0 规格中介绍的空格处理方式不同。 这是因为 SQL Server 中的 XML 分析器只识别有限数量的 DTD 子集(在 XML 1.0 中定义)。 有关 SQL Server 中支持的有限 DTD 子集的详细信息,请参阅 CAST 和 CONVERT (Transact-SQL)

默认情况下,在 XML 分析器将字符串数据转换为 XML 时,如果存在下列任何一种情况,则 XML 分析器将丢弃无关紧要的空格:

  • 未对元素或其祖先元素定义 The xml:space 属性。

  • 某元素或其某一祖先元素上有效的 xml:space 属性具有默认值。

例如:

declare @x xml
set @x = '<root>      <child/>     </root>'
select @x 

结果如下:

<root><child/></root>

不过,您可以更改此行为。 若要为 xml DT 实例保留空格,请使用 CONVERT 运算符,并将其可选的 style 参数的值设置为 1。 例如:

SELECT CONVERT(xml, N'<root>      <child/>     </root>', 1)

如果未使用 style 参数,或将其值设置为 0,则转换 xml DT 实例时不保留无关紧要的空格。 有关在将字符串数据转换为 xml DT 实例时如何使用 CONVERT 运算符及其 style 参数的详细信息,请参阅 CAST 和 CONVERT (Transact-SQL)

示例:将字符串值转换为类型化的 xml 并将其赋给某列

下面的示例将包含 XML 片段的字符串变量转换为 xml 数据类型,然后将其存储在 xml 类型列中:

CREATE TABLE T(c1 int primary key, c2 xml)
go
DECLARE  @s varchar(100)
SET @s = '<Cust><Fname>Andrew</Fname><Lname>Fuller</Lname></Cust>' 

下面的插入操作将字符串隐式转换为 xml 类型:

INSERT INTO T VALUES (3, @s) 

可以使用 cast() 将字符串显式转换为 xml 类型:

INSERT INTO T VALUES (3, cast (@s as xml))

另外,也可以使用 convert(),如下所示:

INSERT INTO T VALUES (3, convert (xml, @s)) 

示例:将字符串转换为类型化的 xml 并将其赋给某个变量

在下面的示例中,将字符串转换为 xml 类型并赋给 xml 数据类型的变量:

declare @x xml
declare  @s varchar(100)
SET @s = '<Cust><Fname>Andrew</Fname><Lname>Fuller</Lname></Cust>' 
set @x =convert (xml, @s)
select @x

将 SELECT 语句与 FOR XML 子句结合使用

可以在 SELECT 语句中使用 FOR XML 子句以返回 XML 形式的结果。 例如:

DECLARE @xmlDoc xml
SET @xmlDoc = (SELECT Column1, Column2
               FROM   Table1, Table2
               WHERE   Some condition
               FOR XML AUTO)
 ...

SELECT 语句将返回文本 XML 片段,该片段将在后面为 xml 数据类型变量赋值的过程中进行分析。

也可以在 FOR XML 子句中使用 TYPE 指令,直接返回 xml 类型的 FOR XML 查询结果:

Declare @xmlDoc xml
SET @xmlDoc = (SELECT ProductModelID, Name
               FROM   Production.ProductModel
               WHERE  ProductModelID=19
               FOR XML AUTO, TYPE)
SELECT @xmlDoc

结果如下:

<Production.ProductModel ProductModelID="19" Name="Mountain-100" />...

在下面的示例中,将 FOR XML 查询的类型化的 xml 结果插入 xml 类型列中:

CREATE TABLE T1 (c1 int, c2 xml)
go
INSERT T1(c1, c2)
SELECT 1, (SELECT ProductModelID, Name
           FROM Production.ProductModel
           WHERE ProductModelID=19
           FOR XML AUTO, TYPE)
SELECT * FROM T1
go

有关 FOR XML 的详细信息,请参阅FOR XML (SQL Server)

注意注意

SQL Server 将 xml 数据类型实例作为不同服务器构造(例如使用 TYPE 指令或在其中使用 xml 数据类型从 SQL 列、变量和输出参数返回 XML 的 FOR XML 查询)的结果返回到客户端。 在客户端应用程序代码中,ADO.NET 访问接口请求以二进制编码形式从服务器发送此 xml 数据类型信息。 但是,如果使用的是不带 TYPE 指令的 FOR XML,则 XML 数据将作为字符串类型返回。 在任何情况下,客户端访问接口都始终能够处理其中任一种形式的 XML 内容。

使用常量赋值

可以在需要 xml 数据类型实例时使用字符串常量。 这与将字符串隐式 CAST 为 XML 相同。 例如:

DECLARE @xmlDoc xml
SET @xmlDoc = '<Cust><Fname>Andrew</Fname><Lname>Fuller</Lname></Cust>' 
-- Or
SET @xmlDoc = N'<?xml version="1.0" encoding="ucs-2"?><doc/>'

上面的示例中,将字符串隐式转换为 xml 数据类型,并将其赋给 xml 类型变量。

下面的示例将常量字符串插入 xml 类型列:

CREATE TABLE T(c1 int primary key, c2 xml)
INSERT INTO T VALUES (3, '<Cust><Fname>Andrew</Fname><Lname>Fuller</Lname></Cust>') 
注意注意

对于类型化的 XML,是针对指定的架构来验证 XML。 有关详细信息,请参阅类型化的 XML 与非类型化的 XML 的比较

使用大容量加载

通过增强的 OPENROWSET (Transact-SQL) 功能,您可以在数据库中大容量加载 XML 文档。 可以将文件中的 XML 实例大容量加载到数据库的 xml 类型列中。 有关工作示例,请参阅大容量导入和导出 XML 文档的示例 (SQL Server)。 有关加载 XML 文档的详细信息,请参阅加载 XML 数据

本节内容

主题

说明

检索和查询 XML 数据

介绍了当 XML 实例存储在数据库中时未保留的部分。

请参阅

概念

类型化的 XML 与非类型化的 XML 的比较

XML 数据修改语言 (XML DML)

XML 数据 (SQL Server)

其他资源

XML 数据类型方法