【问题标题】:How to add xml encoding <?xml version="1.0" encoding="UTF-8"?> to xml Output in SQL Server如何将 xml 编码 <?xml version="1.0" encoding="UTF-8"?> 添加到 SQL Server 中的 xml 输出
【发布时间】:2012-02-18 14:51:03
【问题描述】:

可能与未回答的重复。 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

但我不明白为什么我不能这样做。

【问题讨论】:

  • 为什么?在应用编码之前推迟声明编码是非常合适的。这通常在 XML 序列化程序库中完成。不幸的是,SQL Server 没有内置的序列化 XML 的方法,但您可以将一种方法添加到您的数据库中(如对这个问题和其他问题的回答。)

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


【解决方案1】:

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

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

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

【讨论】:

  • 有没有办法通过命令行做到这一点?我有一个巨大的 XML 文件目录,在大多数文本编辑器中太大而无法处理。
  • 哇!在我发现使用了哪个字符集之前,这是一场噩梦。我曾经添加文件的开头和结尾 echo -e "\n\n$(cat products.xml)\n" > products_with_xml_root. xml
【解决方案2】:

当我读到这篇文章时,我认为这是“线的尽头”......没有解决方案......我几乎放弃了这种方法......但实际上有一种方法可以解决这个限制将 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>

【讨论】:

  • 简单地使用 UTF-8 是不准确的。如果您有 Unicode 字符串,请改用 UCS-2。有关更多详细信息,请参阅 related question 上的 my answer。如果你有一个普通的 varchar 字符串,那么使用“windows-1252”。
  • 这将使数据类型为 varchar 而不是 xml
【解决方案3】:

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

在 SQL Server 2019 之前(目前在 CTP 2.1 中处于测试阶段),没有办法在 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_SaveToFileXML_SaveToFile 函数允许指定任何有效的编码,它会在 XML 声明中设置它并确保使用该编码保存文件。它还具有缩进、换行等选项。仅供参考:虽然免费版本中有许多功能可用,但 XML_SaveToFile 仅在完整(付费)版本中可用。

【讨论】:

    【解决方案4】:

    最近几天我一直在处理这个问题,虽然可能有更好的解决方案,但我对这个 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
    

    【讨论】:

    • 如果您将 select 语句更改为 "select * from dat1.dbo.Products FOR XML AUTO,ELEMENTS,ROOT('products')",则生成的 XML 将在包含外部标记的情况下有效。无需手动添加,也不是 bcp 的错...
    • 感谢您提供的额外信息!老实说,我在寻找文档时绞尽脑汁,但找不到我真正想要的东西。谢天谢地,我不必再使用它了:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多