【问题标题】:.NET DataSet.GetXml() - what's the default encoding?.NET DataSet.GetXml() - 默认编码是什么?
【发布时间】:2010-12-24 23:08:40
【问题描述】:

现有应用程序在SQLServer 2000 中将XML 传递给一个sproc,输入参数数据类型为TEXT; XML 派生自 Dataset.GetXML()。但我注意到它没有指定编码。

因此,当用户将不适当的字符潜入数据集中时,特别是 ASCII 146(似乎是撇号)而不是 ASCII 39(单引号),存储过程会失败。

一种方法是在 GetXML 的结果前面加上

<?xml version="1.0" encoding="ISO-8859-1"?>

它在这种情况下有效,但是确保存储过程不会崩溃(如果弹出其他无法预料的字符)的更正确方法是什么?

PS。我怀疑用户在 MS-Word 或类似的编辑器中输入文本,然后复制并粘贴到应用程序的输入字段中;我可能希望允许用户继续以这种方式工作,只需要防止崩溃。

编辑:我正在寻找确认或否认某些方面的答案,例如:
- 根据标题,如果 XML 中没有指定,默认编码是什么?
- 编码 ISO-8859-1 是否适合使用?
- 如果有更好的编码可以包含英语世界中的更多字符,因此不太可能导致存储过程中的错误?
- 您是否会在应用程序的 UI 级别过滤标准 ASCII(仅 0 到 127),并且不允许扩展 ASCII?
- 任何其他相关细节。

【问题讨论】:

    标签: xml encoding dataset xml-parsing


    【解决方案1】:

    我相信您的方法应该是使用 WriteXml 而不是 GetXml。这应该允许您指定编码。

    但是,请注意,您必须通过中间流进行写入 - 如果您直接输出到字符串,它将始终使用 UTF-16。由于您使用的是 TEXT 列,这将允许对 TEXT 无效的字符。

    【讨论】:

    • 按照我的例子这样做有什么问题,连接 [xml 编码] + DataSet.GetXml() ?
    • 1) 不要使用字符串连接来操作 XML。 XML 和字符串之间的规则存在差异。 2)您的方法仅声明编码是什么 - 它根本不会更改编码。
    【解决方案2】:

    DataSet.GetXml() 返回一个string。在 .NET 中,字符串在内部使用 UTF-16 进行编码,但这在这里并不重要。

    字符串中没有&lt;?xml encoding=...&gt; 声明的原因是该声明仅在解析字节流中的XML 时有用或需要。 .NET 字符串不是字节流,它只是具有明确定义的代码点语义(即 Unicode)的文本,因此不需要它。

    如果没有 XML 编码声明,则在没有 BOM 的情况下,XML 解析器将采用 UTF-8。但是,在您的情况下,它也完全无关紧要,因为问题不在于 XML 解析器(当 XML 存储在 TEXT 列中时,SQL Server 不会解析 XML)。问题是您的 XML 包含一些 Unicode 字符,而 TEXT 是非 Unicode SQL 类型。

    您可以使用Encoding.GetBytes() 方法将string 编码为任何编码。

    【讨论】:

    • 错误假设,该列不是 TEXT,仅使用 TEXT 类型的参数来接受 XML 字符串;使用 TEXT 是因为 varchar(8000) 有长度限制;问题 与 sqlserver 上的解析器有关。服务器:消息 6603,级别 16,状态 1,过程 sp_xml_preparedocument,第 40 行 XML 解析错误:在文本内容中发现无效字符。正如我所说,当我将 XML 字符串声明为 ISO-8859-1 时,存储过程中不会发生错误,因此解析器将 ASCII 146 视为可接受的。
    • 其实还是TEXT的问题。具体来说,当您将 Unicode string 传递给存储过程时,必须将其转换为非 Unicode 编码以匹配 TEXT;结果当然不是使用 UTF 编码的,要使用哪种编码进行转换也不容易确定。如果您可以控制 sproc,只需将 TEXT 替换为 NTEXT,并且不要为编码烦恼
    • 在阅读您的最后一条评论之前,我得出了相同的结论来使用 NTEXT,那么我不需要声明
      ?xml version="1.0" encoding="ISO-8859 -1"?
      让它工作(或者不需要像你所说的那样打扰编码)。您能否澄清一些事情:
      您是说如果我使用 NTEXT,我传递的 xml 字符串将被 xml 解析器解释为 UTF-16?
      为什么保留 TEXT 并将 xml 字符串声明为 ISO-8859-1 有效?
    • 显然,当 ADO.NET MSSQL 提供程序将 .NET Unicode 字符串转换为 TEXT 时,它使用 ISO-8859-1 作为编码(我怀疑它要么使用当前系统区域设置,或数据库中指定的代码页)。因此,字符串一旦进入 SQL,就使用 ISO-8859-1 进行编码(只要它可以表示原始字符串中的字符),然后 MSSQL 中的 XML 解析器将其视为字节序列,并假定 UTF-8 (或选择您的显式编码声明)。对于 NTEXT,我希望它能将其视为 Unicode 文本而不是原始字节。
    猜你喜欢
    • 2013-03-03
    • 2010-11-03
    • 1970-01-01
    • 2019-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多