栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

使用StringWriter进行XML序列化

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

使用StringWriter进行XML序列化

< TL; DR>问题实际上很简单:您没有将声明的编码(在XML声明中)与输入参数的数据类型匹配。如果您是手动添加

<?xmlversion="1.0"encoding="utf-8"?><test/>
到字符串中,则声明的
SqlParameter
类型为
SqlDbType.Xml
SqlDbType.NVarChar
会给您“无法切换编码”错误。然后,当通过T-
SQL手动插入时,由于将声明的编码切换为
utf-16
,因此您显然插入了一个
VARCHAR
字符串(不以大写字母“
N”作为前缀,因此是8位编码,例如UTF-8)。而不是
NVARCHAR
字符串(以大写字母“ N”为前缀,因此为16位UTF-16 LE编码)。

该修复程序应该很简单:

  1. 在第一种情况下,添加声明时说明
    encoding="utf-8"
    :只需不添加XML声明。
  2. 在第二种情况下,添加声明时
    encoding="utf-16"
    1. 根本不添加XML声明,或者
    2. 只需在输入参数类型中添加“ N”:
      SqlDbType.NVarChar
      而不是: -)
      SqlDbType.VarChar
      (甚至可能切换为using
      SqlDbType.Xml

(详细回复如下)


这里的所有答案都过于复杂和不必要(无论克里斯蒂安和乔恩分别获得121和184的赞成票)。他们可能会提供有效的代码,但没有一个人真正回答问题。问题在于,没有人真正地理解这个问题,最终是关于SQL
Server中XML数据类型如何工作的问题。这两个显然很聪明的人并不反对,但是这个问题与序列化到XML几乎没有关系。将XML数据保存到SQL
Server中比这里所隐含的要容易得多。

只要您遵循如何在SQL
Server中创建XML数据的规则,XML的产生方式实际上并不重要。在以下问题的答案中,我得到了更详尽的解释(包括工作示例代码,以说明以下要点):在将XML插入SQL
Server时,如何解决“无法切换编码”错误,但是基础是:

  1. XML声明是可选的
  2. XML数据类型始终将字符串存储为UCS-2 / UTF-16 LE
  3. 如果您的XML是UCS-2 / UTF-16 LE,则您:
    1. NVARCHAr(MAX)
      XML
      /
      SqlDbType.NVarChar
      (maxsize = -1)或的形式传递数据
      SqlDbType.Xml
      ,或者如果使用字符串文字,则必须以大写字母“ N”作为前缀。
    2. 如果指定XML声明,则必须为“ UCS-2”或“ UTF-16”(此处无实际差异)
  4. 如果您的XML是8位编码的(例如“ UTF-8” /“ iso-8859-1” /“ Windows-1252”),则您:
    1. 如果编码与数据库默认排序规则指定的代码页不同,则需要指定XML声明
    2. 您必须以
      VARCHAr(MAX)
      /
      SqlDbType.VarChar
      (maxsize = -1)的形式传递数据,或者如果使用字符串文字,则该数据 不得 以大写字母“ N”作为前缀。
    3. 无论使用哪种8位编码,XML声明中注明的“编码”都必须与字节的实际编码匹配。
    4. 8位编码将通过XML数据类型转换为UTF-16 LE

有了上面的概述考虑点, 考虑到在.NET字符串 总是 UTF-16 LE / UCS-2
LE(有编码的那些方面没有区别),我们可以回答您的问题:

为什么在以后需要字符串时不使用StringWriter序列化对象是有原因的吗?

不,您的

StringWriter
代码看起来还不错(至少在使用问题的第二个代码块进行的有限测试中,我看不到任何问题)。

这样,将编码设置为UTF-16(在xml标记中)就不会起作用吗?

无需提供XML声明。如果缺少该字符串, 则如果
将字符串作为

NVARCHAR
(即
SqlDbType.NVarChar
)或
XML
(即
SqlDbType.Xml
)传递给SQL
Server,则假定编码为UTF-16 LE
。如果以
VARCHAR
(即
SqlDbType.VarChar
)传入,则假定编码为默认的8位代码页。如果您有任何非标准ASCII字符(即值128和更高),并且以传入
VARCHAR
,那么您可能会看到“?”
用于BMP字符和“ ??” SQL Server将把.NET中的UTF-16字符串转换为当前数据库代码页的8位字符串,然后再将其转换回UTF-16 /
UCS-2。但是您不应该得到任何错误。

另一方面,如果确实指定XML声明,则 必须 使用匹配的8位或16位数据类型传递到SQL
Server。因此,如果您有声明说明编码为UCS-2或UTF-16,则 必须

SqlDbType.NVarChar
或形式传入
SqlDbType.Xml
。或者,如果你有一个声明,表示编码是8位的选项之一(即
UTF-8
Windows-1252
iso-8859-1
等等),那么你
必须 在为合格
SqlDbType.VarChar
。无法将声明的编码与正确的8位或16位SQL
Server数据类型匹配,将导致您收到“无法切换编码”错误。

例如,使用

StringWriter
基于您的序列化代码,我只打印了XML的结果字符串,并将其用于SSMS。如下所示,其中包含XML声明(因为
StringWriter
没有
OmitXmlDeclaration
类似的选项
XmlWriter
),只要您将字符串作为正确的SQL
Server数据类型传递,就不会出现问题:

-- Upper-case "N" prefix == NVARCHAR, hence no error:DECLARE @Xml XML = N'<?xml version="1.0" encoding="utf-16"?><string>Test ሴ
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/452071.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号