具有汉字文本内容的XmlDocument未使用XmlTextWriter正确编码到ISO-8859-1

时间:2018-01-23 13:16:07

标签: c# xml encoding iso-8859-1

我有XmlDocument在其文本内容中包含汉字,我需要使用ISO-8859-1编码将其写入流。当我这样做时,没有一个汉字字符被正确编码,而是替换为" ??"。

以下是演示如何从XmlDocument

编写XML的示例代码
MemoryStream mStream = new MemoryStream();
Encoding enc = Encoding.GetEncoding("ISO-8859-1");
XmlTextWriter writer = new XmlTextWriter(mStream,enc);
doc.WriteTo(writer);
writer.Flush();
mStream.Flush();
mStream.Position = 0;
StreamReader sReader = new StreamReader(mStream, enc);
String formattedXML = sReader.ReadToEnd();

在这种特定情况下,如何正确编码汉字?

1 个答案:

答案 0 :(得分:0)

正如评论中所述,?字符会显示,因为编码ISO-8859-1不支持汉字字符,因此它会将?替换为后备字符。编码回退在Documentation Remarks for Encoding

中讨论
  

请注意,编码类允许错误(不支持的字符):

     
      
  • 默默地改为"?"字符。
  •   
  • 使用"最合适的"字符。
  •   
  • 通过使用带有U + FFFD Unicode替换字符的EncoderFallbackDecoderFallback类,更改为特定于应用程序的行为。
  •   

这是您所看到的行为。

但是,即使ISO-8859-1不支持汉字字符,您也可以切换到XmlWriter.Create(Stream, XmlWriterSettings)返回的较新XmlWriter并在{{{{}}上设置编码,从而获得更好的结果。 3}}像这样:

MemoryStream mStream = new MemoryStream();

var enc = Encoding.GetEncoding("ISO-8859-1");
var settings = new XmlWriterSettings
{
    Encoding = enc,
    CloseOutput = false,
    // Remove to enable the XML declaration if you want it.  XmlTextWriter doesn't include it automatically.
    OmitXmlDeclaration = true,  
};
using (var writer = XmlWriter.Create(mStream, settings))
{
    doc.WriteTo(writer);
}

mStream.Position = 0;
var sReader = new StreamReader(mStream, enc);
var formattedXML = sReader.ReadToEnd();

通过设置Encoding的{​​{1}}属性,只要当前编码不支持某个字符,就会使XML编写器知道,并自动将其替换为XML {{3} 而不是一些硬编码的后备。

E.g。假设你有以下XML:

XmlWriterSettings

然后您的代码将输出以下内容,将所有汉字映射到单个后备字符:

<Root>
  <string>畑 はたけ hatake "field of crops"</string>
</Root>

新版本将输出:

<Root><string>? ??? hatake "field of crops"</string></Root>

请注意,汉字字符已被<Root><string>&#x7551; &#x306F;&#x305F;&#x3051; hatake "field of crops"</string></Root> 等字符实体替换?所有兼容的XML解析器都会识别并重建这些字符,因此,尽管您的首选编码不支持汉字,但不会丢失任何信息。

最后,作为旁注,XmlWriterSettings.Encoding表示:

  

从.NET Framework 2.0开始,我们建议您改用System.Xml.XmlWriter类。

一般来说,用&#x7551;替换它是一个好主意。

示例character entity reference演示了两个编写者的用法,并断言XmlWriter生成的XML在语义上等同于原始XML,尽管字符被转义。