如何在SQL Server中添加xml编码<! - ?xml version =“1.0”encoding =“UTF-8”? - >到xml输出

时间:2012-01-25 12:04:38

标签: sql-server xml sql-server-2008 utf-8 character-encoding

可能是未答复的副本。 SQL Server 2008 - Add XML Declaration to XML Output

如果可能,请告诉我。我在一些博客中读到了

http://forums.asp.net/t/1455808.aspx/1

http://www.devnewsgroups.net/group/microsoft.public.sqlserver.xml/topic60022.aspx

但我无法理解为什么我不能这样做。

4 个答案:

答案 0 :(得分:35)

您必须手动添加它。 SQL Server始终在内部将xml存储为ucs-2,因此SQL无法生成utf-8编码头

请参阅MSDN上的"Limitations of the xml Data Type"

  

在xml数据类型实例中存储XML数据时,不会保留XML声明PI,例如<?xml version='1.0'?>。这是设计的。数据转换为xml类型后,XML声明(<?xml ... ?>)及其属性(版本/编码/独立)将丢失。 XML声明被视为XML解析器的指令。 XML数据在内部存储为ucs-2。

答案 1 :(得分:5)

当我读到这篇文章时,我认为这是“行尾”......没有解决方案......我几乎放弃了这种方法......但实际上有办法解决这个问题将XML转换为varchar(max),然后将声明附加到字符串的开头。以下文章说明了如何:

Using SQL Server "FOR XML": Convert Result Datatype to Text/varchar/string whatever?

一个简单的例子看起来像这样:

SELECT 'MY DATA' As MyColumn INTO #MyTable 
SELECT '<?xml version="1.0" encoding="UTF-8"?>' + 
CAST((SELECT MyColumn FROM #MyTable FOR XML PATH('')) AS VARCHAR(MAX)) AS XmlData
DROP TABLE #MyTable 

输出:

<?xml version="1.0" encoding="UTF-8"?>
<MyColumn>MY DATA</MyColumn>

答案 2 :(得分:2)

在技术上正确的情况下,“手动添加”的公认答案是不完整的,因此具有误导性。只需在XML声明中添加所需的任何“编码”,就不会更改字符串的实际编码。有时候可以。如果您指定“ UTF-8”并将XML数据转换为VARCHAR,则只要 all 个字符都是标准ASCII字符(值1-127),那么可以肯定的是,它是UTF-8(至少没有明显的区别)。但是,如果有任何个字符的值等于或大于128,则您 not 不会拥有UTF-8编码的XML文档。而且,如果将XML数据转换为NVARCHAR,则无论您在XML声明中手动指定了什么,都将拥有UTF-16编码的文档。您应该仅在使用实际编码的情况下指定编码。

直到SQL Server 2019(当前处于CTP 2.1的beta版)之前,都没有办法在SQL Server中将编码转换为UTF-8,至少没有使用SQLCLR。但是在SQL Server 2019中,您现在可以将XML转换为实际的UTF-8:

DECLARE @XML XML;
SET @XML = N'<test attr="&#x1F60E;"/>';
SELECT @XML,
       CONVERT(VARBINARY(100), CONVERT(NVARCHAR(MAX), @XML)), -- UTF-16 / UCS-2
       CONVERT(VARBINARY(100),
               CONVERT(VARCHAR(MAX),
                       CONVERT(NVARCHAR(MAX), @XML) COLLATE Latin1_General_100_CI_AS_SC_UTF8)
              ); -- UTF-8

返回:

Column 1: <test attr="" />
Column 2: 0x3C007400650073007400200061007400740072003D0022003DD80EDE22002F003E00
Column 3: 0x3C7465737420617474723D223F3F222F3E

由于很多人暂时不会使用SQL Server 2019,因此可以通过SQLCLR实现。您可以使用.NET Xml类(例如XmlWriter)通过各种选项将其导出。实际上,我创建了一个SQLCLR函数库SQL#,其中包括这样的函数: XML_SaveToFile XML_SaveToFile 函数允许指定任何有效的编码,它将在XML声明中进行设置,并确保使用该编码保存文件。还提供缩进,换行等选项。仅供参考:免费版本中有许多功能,而 XML_SaveToFile 仅在完整(付费)版本中可用。

答案 3 :(得分:0)

我在最后几天一直在处理这个问题,虽然可能有更好的解决方案,但我对这个bash脚本感到非常满意:

iconv -f UCS-2 -t UTF-8 products.xml > products_utf8.xml
echo "<?xml version='1.0'?>\n<products>\n$(cat products_utf8.xml)\n</products>" > products_utf8_final.xml

基本上,这个脚本将获得一个从可怕的bcp软件生成的文件,它生成不完整和无效的XML数据,将其从UCS-2格式转换为UTF-8(第一行),并在开头和结尾添加所需文件(脚本的第二行)有效且完整。

它对我有用。我用BCP生成XML文件的脚本是:

bcp.exe "select * from dat1.dbo.Products FOR XML AUTO,ELEMENTS” queryout "C:\products.xml" -T -w -r -S .\SQLEXPRESS