SQL Server 2008 - 将XML声明添加到XML输出

Pix*_*ted 10 xml sql-server encoding

我一直在与这个争夺几天,我正在寻求使用以下语法自动化XML输出

 SELECT (
   SELECT CONVERT(VARCHAR(10),GETDATE(),103)
   FOR XML PATH('DataVersion'), 
     TYPE
   ),
   (  
   SELECT CoNum,
     CoName,
     CONVERT(VARCHAR(10),AccountToDate,103) 'DLA',
     LAFileNet
   FROM @XMLOutput  
   FOR XML PATH('Company'),
     TYPE  
   )
 FOR XML PATH(''),
   ROOT('Companies')
Run Code Online (Sandbox Code Playgroud)

这会创建以下输出

<Companies>
  <DataVersion>15/11/2010</DataVersion>
  <Company>
    <CoNum>111</CoNum>
    <CoName>ABCLmt</CoName>
    <DLA>12/12/2010</DLA>
    <LAFileNet>1234</LAFileNet>
  </Company>
  <Company>
    <CoNum>222</CoNum>
    <CoName>DEFLmt</CoName>
    <DLA>12/12/2007</DLA>
    <LAFileNet>5678</LAFileNet>
  </Company>
</Companies>
Run Code Online (Sandbox Code Playgroud)

我正在努力的是如何将XML声明添加<?xml version="1.0" encoding="ISO-8859-1" ?>到输出的顶部?

更新1:我认为我需要在SQL服务器中创建XML模式来定义xsl:output是否正确?然后将输出分配给该架构?

更新2:此后发现这些链接 http://forums.asp.net/t/1455808.aspx - 查看健康的评论.另外 http://www.devnewsgroups.net/group/microsoft.public.sqlserver.xml/topic60022.aspx

Ril*_*jor 7

TL; DR

连接这个:<?xml version="1.0" encoding="windows-1252" ?>用你的XML转换为varchar(max).

细节

我同意j0N45,架构不会改变任何东西.正如他所引用的答案指出:

您必须手动添加它.

我在另一个答案中提供了一些示例代码.基本上,您CONVERT将XML转换为varchar或者nvarchar然后将其与XML声明连接起来,例如<?xml version="1.0" encoding="windows-1252" ?>.

但是,选择正确的编码很重要.SQL Server根据其排序规则设置生成非Unicode字符串.默认情况下,这将由数据库排序规则设置控制,您可以使用此SQL确定:

SELECT DATABASEPROPERTYEX('ExampleDatabaseName', 'Collation');
Run Code Online (Sandbox Code Playgroud)

常见的默认排序规则是"SQL_Latin1_General_CP1_CI_AS",其代码页为1252.您可以使用此SQL检索代码页:

SELECT COLLATIONPROPERTY('SQL_Latin1_General_CP1_CI_AS', 'CodePage') AS 'CodePage';
Run Code Online (Sandbox Code Playgroud)

对于代码页1252,您应使用编码名称" windows-1252 ".使用"ISO-8859-1"是不准确的.您可以使用"bullet"字符进行测试:•.它的Unicode Code Point值为8226(Hex 2022).您可以使用以下代码可靠地生成SQL中的字符,无论整理如何:

SELECT NCHAR(8226);
Run Code Online (Sandbox Code Playgroud)

它在windows-1252代码页中的代码点为149,因此如果您使用"SQL_Latin1_General_CP1_CI_AS"的常用默认排序规则,那么您也可以使用以下方法生成它:

SELECT CHAR(149);
Run Code Online (Sandbox Code Playgroud)

但是,CHAR(149)不会成为所有排序规则中的子弹.例如,如果您尝试这样做:

SELECT CONVERT(char(1),char(149)) COLLATE Chinese_Hong_Kong_Stroke_90_BIN;
Run Code Online (Sandbox Code Playgroud)

你根本没有得到子弹.

"ISO-8859-1"代码页是Windows-28591.SQL Server排序规则(无论如何在2005年)都没有使用该代码页.您可以使用以下命令获取完整的代码页列表:

SELECT [Name], [Description], [CodePage] = COLLATIONPROPERTY([Name], 'CodePage')
FROM ::fn_helpcollations()
ORDER BY [CodePage] DESC;
Run Code Online (Sandbox Code Playgroud)

您可以通过尝试在SQL本身中使用它来进一步验证"ISO-8859-1"是错误的选择.以下SQL:

SELECT CONVERT(xml,'<?xml version="1.0" encoding="ISO-8859-1"?><test>•</test>');
Run Code Online (Sandbox Code Playgroud)

将生成不包含项目符号的XML.实际上,它不会产生任何字符,因为ISO-8859-1没有为代码点149定义字符.

SQL Server以不同方式处理Unicode字符串.使用Unicode字符串(nvarchar),"不需要不同的代码页来处理不同的字符集".但是,SQL Server不使用"UTF-8"编码.如果您尝试在SQL本身中使用它:

SELECT CONVERT(xml,N'<?xml version="1.0" encoding="UTF-8"?><test>•</test>');
Run Code Online (Sandbox Code Playgroud)

你会收到一个错误:

消息9402,级别16,状态1,行1 XML解析:第1行,字符38,无法切换编码

相反,SQL使用"U​​CS-2"编码,因此这将起作用:

SELECT CONVERT(xml,N'<?xml version="1.0" encoding="UCS-2"?><test>•</test>');
Run Code Online (Sandbox Code Playgroud)