我们使用C#调用基于Java的Web服务.从返回的强类型数据中,我们创建了一个将传递给sql Server的XML文件. Web服务数据使用UTF-8进行编码,因此在C#中我们创建文件,并在适当的地方指定UTF-8:
var encodingType = Encoding.UTF8; // logic removed... var xdoc = new XDocument(); xdoc.Declaration = new XDeclaration("1.0",encodingType.WebName,"yes"); // logic removed... System.IO.File.WriteAllText(xmlFullPath,xdoc.Declaration.ToString() + xdoc.Document.ToString(),encodingType);
这将在磁盘上创建一个包含以下(缩写)数据的XML文件:
<?xml version="1.0" encoding="utf-8" standalone="yes"?> <records> <r RecordName="Option - Foo" /> <r RecordName="Option – Bar" /> </records>
请注意,在第二条记录中,– 与 – 不同.我相信第二个例子是en-dash.
如果我在Firefox / IE / VS2015中打开该XML文件.它打开没有错误. W3C XML validator也可以正常工作.但是,SSMS 2012不喜欢它:
declare @xml XML = '<?xml version="1.0" encoding="utf-8" standalone="yes"?><records> <r RecordName="Option - Foo" /> <r RecordName="Option – Bar" /> </records>';
XML parsing: line 3,character 25,illegal xml character
那么为什么en-dash会导致错误呢?从我的研究来看,似乎是这样
…only a few entities that need escaping: <,>,\,’ and & in both HTML and
XML.
07005
…其中en-dash不是一个.编码版本(替换 – 和–)工作正常.
UPDATE
根据输入,人们声明en-dash不被识别为UTF-8,但它在此处列出http://www.fileformat.info/info/unicode/char/2013/index.htm
那么,作为一个完全合法的角色,为什么SSMS在以XML格式传递时不会读取它(使用UTF-8或UTF-16)?
declare @xml XML = N'<?xml version="1.0" encoding="utf-16" standalone="yes"?><records> <r RecordName="Option - Foo" /> <r RecordName="Option – Bar" /> </records>'; select @xml (No column name) <records><r RecordName="Option - Foo" /><r RecordName="Option – Bar" /></records>
推测编辑
这两个都失败了非法的xml字符:
set @xml = '<?xml version="1.0" encoding="utf-8"?><x> – </x>' set @xml = '<?xml version="1.0" encoding="utf-16"?><x> – </x>'
因为它们将非unicode varchar传递给XML解析器;字符串包含Unicode,因此必须这样处理,即作为nvarchar(utf-16)(否则包含 – 的3个字节被误解为多个字符,并且一个或多个不在XML的可接受范围内)
这会将nvarchar字符串传递给解析器,
但由于无法切换编码而失败:
set @xml = N'<?xml version="1.0" encoding="utf-8"?><x> – </x>'
这是因为nvarchar(utf-16)字符串被传递给XML解析器,但XML文档声明它的utf-8并且 – 在两种编码中不相同
这一切都有效,因为一切都是utf-16
set @xml = N'<?xml version="1.0" encoding="utf-16"?><x> – </x>'