从xml文件中读取字符时,控制台打印错误字符

时间:2015-04-04 17:50:32

标签: c# .net unicode

我想解析xml文件以打印字符控制台或winforms。它看起来像这样,

<?xml version="1.0" encoding="UTF-8"?>
<kanjidic2>
<header>
  <file_version>4</file_version>
  <database_version>2015-093</database_version>
  <date_of_creation>2015-04-03</date_of_creation>
</header>
<character>
  <literal>亜</literal>
  <codepoint>
    <cp_value cp_type="ucs">4e9c</cp_value>
    <cp_value cp_type="jis208">16-01</cp_value>
  </codepoint>
</character>
<character>
  <literal>唖</literal>
  <codepoint>
    <cp_value cp_type="ucs">5516</cp_value>
    <cp_value cp_type="jis208">16-2</cp_value>
  </codepoint>
</character>

...
</kanjidic2>

literal标记中的字符是要打印的字符。字符本身以UTF8编码(提供者说)。 我用这段代码解析并在控制台中打印它。

class Program
{
    static void Main(string[] args)
    {
        Console.OutputEncoding = Encoding.UTF8;

        foreach (Kanji kanji in Parse())
        {
            Console.WriteLine(kanji.Character);
        }

        Console.ReadKey();
    }

    private static IEnumerable<Kanji> Parse()
    {
        var doc = new XmlDocument();
        doc.Load("kanjidic2.xml");

        XmlNodeList nodes = doc.DocumentElement.SelectNodes("/kanjidic2/character");

        foreach (XmlNode node in nodes)
        {
            yield return new Kanji { Character = node.SelectSingleNode("literal").InnerText };
        }
    }
}

public class Kanji
{
    public string Character { get; set; }
}

当我运行程序时,它开始打印字符,但它不是我在literal中看到的字符(我认为没有人可以阅读它)。 我尝试将控制台输出编码更改为Unicode,这次打印正确的字符。

问题是,当我将输出编码设置为UTF8时,为什么控制台不能正确打印字符?

是不是因为它读取了以UTF8编码的字符并将该字符作为Unicode存储在内存中(这意味着.net中的UTF16?)?如果是这样的话,为什么它不能像我第一次设置它那样将字符转换回UTF8。

2 个答案:

答案 0 :(得分:0)

尝试以UTF8字节加载xml,然后加载xml文件:

 byte[] encodedString = Encoding.UTF8.GetBytes(xmlString);
using (MemoryStream ms = new MemoryStream(encodedString))
{
    ms.Flush();
    ms.Position = 0;
   XmlDocument xmlDoc = new XmlDocument();
   xmlDoc.Load(ms);
}

如果你有一个文件而不是一个xml字符串,那么首先加载为像这样的rgular文件

 var xmlString= File.ReadAllText(FilePath,Encoding.Default)

答案 1 :(得分:0)

您可能会遇到几个潜在的问题。

  1. 控制台在显示其他字符集(例如汉字)时出现问题,无需额外的工作或代码。您可以尝试changing the Console font到TrueType字体,例如Consolas或Courier New。或者对于UTF-32,请查看代码示例here
  2. 您的xml文件是没有BOM的UTF8,如果这是静态的(不会更改),那么最好在代码中指定它。您的gist正在使用Encoding.Default,但当我将其更改为Encoding.UTF8时,汉字字符串是正确的。我查看了methods for detecting the encoding,但您需要确定您的XML文件是否会改变编码。
  3. 我在十六进制编辑器中查看了第一个<literal>亜</literal>,它是E4 BA 9C,但是当我将该字符粘贴到Visual Studio中时,它只是E4 9C。我相信BAcombining character。如果编码错误,您可能会看到亜。如果您不使用TTF字体,您将看到疯狂的字符。即使在我的系统上使用Consolas,E4 9C字符串也会显示一个带框的问号,但是当我复制并粘贴它时,它就是正确的字符。