定义 XML 数据的序列化

适用于:yesSQL Server(所有支持的版本)YesAzure SQL 数据库

显式或隐式将 xml 数据类型强制转换为SQL字符串或二进制类型时,将根据本文中所述的规则序列化 xml 数据类型的内容。

序列化编码

如果 SQL 目标类型是 VARBINARY,则将使用前面具有 UTF-16 字节顺序标记且没有 XML 声明的 UTF-16 对结果进行序列化。 如果目标类型太小,将会引发错误。

例如:

select CAST(CAST(N'<Δ/>' as XML) as VARBINARY(MAX))

结果如下:

0xFFFE3C0094032F003E00

如果 SQL 目标类型是 NVARCHAR 或 NCHAR,则使用前面没有字节顺序标记且没有 XML 声明的 UTF-16 对结果进行序列化。 如果目标类型太小,将会引发错误。

例如:

select CAST(CAST(N'<Δ/>' as XML) as NVARCHAR(MAX))

结果如下:

<Δ/>

如果 SQL 目标类型是 VARCHAR 或 CHAR,则使用与数据库的排序规则代码页对应的编码(既没有字节顺序标记,也没有 XML 声明)对结果进行序列化。 如果目标类型太小或值无法映射到目标排序规则代码页,则会引发错误。

例如:

select CAST(CAST(N'<Δ/>' as XML) as VARCHAR(MAX))

如果当前排序规则的代码页不能表示 Unicode 字符 Uni,或者它将在特定编码中表示,则可能会导致错误。

将 XML 结果返回到客户端时,将用 UTF-16 编码发送数据。 然后,客户端提供程序将根据 API 规则显示该数据。

XML 结构的序列化

用通常的方式对 xml 数据类型的内容进行序列化。 确切地说,就是将元素节点映射到元素标记,将文本节点映射到文本内容。 不过,对字符进行实体化的环境以及对类型化的原子值进行序列化的方法将在下面两节中进行介绍。

序列化过程中 XML 字符的实体化

应该能够对每个序列化的 XML 结构进行重新分析。 因此,某些字符必须以实体化的方式进行序列化,以便通过 XML 分析程序的规范化阶段保留字符的往返功能。 不过,还必须对某些字符进行实体化,以便文档的格式正确并能够被分析。 下面是序列化期间应用的实体化规则:

  • The characters &, <, and > are always entitized to &amp;, &lt;, and &gt; respectively, if they occur inside an attribute value or element content.

  • 因为 SQL Server 使用引号 (U+0022) 来闭合属性值,所以将属性值中的引号实体化为 &quot;

  • 仅在服务器上进行转换时,将代理项对实体化为单个数字字符引用。 例如,代理项对 U+D800 U+DF00 将实体化为数字字符引用 &#x00010300;

  • 为了保护 TAB (U+0009) 和换行符 (LF、U+000A) 在分析期间被规范化,它们将分别缩进其数值字符引用 &#x9; ,并在 &#xA; 属性值内分别进行规范化。

  • 为了防止回车 (CR,U+000D) 在分析期间被规范化,它会在属性值和元素内容中向数值字符引用 &#xD; 进行实体化。

  • 为了保护仅包含空格的文本节点,将其中一个空格字符(通常是最后一个)实体化为它的数字字符引用。 这样,重新分析将保留空格文本节点,而不考虑分析期间空格处理的设置。

例如:

DECLARE @u NVARCHAR(50)
set @u = N'<a a="
    '+NCHAR(0xD800)+NCHAR(0xDF00)+N'>">   '+NCHAR(0xA)+N'</a>'
SELECT CAST(CONVERT(XML,@u,1) as NVARCHAR(50));

结果如下:

<a a="
    𐌀>">
</a>

如果不想应用最后一个空格保护规则,则可以在从 xml 转换为字符串或二进制类型时使用显式 CONVERT 选项 1。 例如,为避免实体化,可以执行以下语句:

SELECT CONVERT(NVARCHAR(50), CONVERT(XML, '<a>   </a>', 1), 1);

query () 方法 (xml 数据类型) 生成 xml 数据类型实例。 因此,转换为字符串或二进制类型的方法的任何结果 query() 都根据前面所述的规则进行实体化。 如果要获取未进行实体化的字符串值,应改用 value () 方法 (xml 数据类型) 。 下面是使用 query() 方法的示例:

DECLARE @x xml
SET @x = N'<a>This example contains an entitized char: <.</a>'
SELECT @x.query('/a/text()');

结果如下:

This example contains an entitized char: <.

下面是使用 value() 方法的示例:

SELECT @x.value('(/a/text())[1]', 'nvarchar(100)');

结果如下:

This example contains an entitized char: <.

序列化类型化的 xml 数据类型

类型化的 xml 数据类型实例包括根据其 XML 架构类型类型化的值。 根据这些值的 XML 架构类型对这些值进行序列化,使用的格式与 XQuery 转换为 xs:string 所产生的格式相同。 有关详细信息,请参阅 XQuery 中的类型转换规则

例如,下面的示例显示了将 xs:double 值 1.34e1 序列化为 13.4:

declare @x xml
set @x =''
select CAST(@x.query('1.34e1') as nvarchar(50));

将返回字符串值 13.4。

请参阅