从 xml 文件读取字符时控制台打印错误字符
Console print wrong character when read character from xml file
我想解析 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
中看到的字符(我认为 none 可以读取它)。
我尝试将控制台输出编码更改为 Unicode
这次它可以正确打印字符。
问题是为什么当我设置输出编码为UTF8时控制台不能正确打印字符?
是否因为它读取以 UTF8 编码的字符并将该字符作为 Unicode 存储在内存中(这意味着在 .net 中为 UTF16?)?如果是这样,为什么它不能像我第一次设置的那样将字符转换回 UTF8。
尝试以 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 字符串,只需首先加载为这样的常规文件
var xmlString= File.ReadAllText(FilePath,Encoding.Default)
您可能会在这里遇到几个潜在的问题。
- 控制台在显示其他字符集(例如汉字)时出现问题,无需额外的工作或代码。你可以试试 changing the Console font to a TrueType font such as Consolas or Courier New. Or for UTF-32, look at the code samples here.
- 您的 xml 文件是没有 BOM 的 UTF8,如果这是静态的(不会更改),那么您最好在代码中指定它。您的 gist is using
Encoding.Default
but when I changed it to Encoding.UTF8
the Kanji string was correct. I looked at methods for detecting the encoding,但您需要决定 XML 文件是否会更改编码。
- 我在十六进制编辑器中查看了第一个
<literal>亜</literal>
,它是E4 BA 9C
,但是当我将字符粘贴到Visual Studio时,它只是E4 9C
。我相信 BA
是 combining character。如果编码错误,您可能会看到 亜
。如果你没有使用 TTF 字体,你会看到疯狂的字符。即使在我的系统上使用 Consolas,E4 9C
字符串显示一个带框的问号,但当我复制并粘贴时它是正确的字符。
我想解析 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
中看到的字符(我认为 none 可以读取它)。
我尝试将控制台输出编码更改为 Unicode
这次它可以正确打印字符。
问题是为什么当我设置输出编码为UTF8时控制台不能正确打印字符?
是否因为它读取以 UTF8 编码的字符并将该字符作为 Unicode 存储在内存中(这意味着在 .net 中为 UTF16?)?如果是这样,为什么它不能像我第一次设置的那样将字符转换回 UTF8。
尝试以 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 字符串,只需首先加载为这样的常规文件
var xmlString= File.ReadAllText(FilePath,Encoding.Default)
您可能会在这里遇到几个潜在的问题。
- 控制台在显示其他字符集(例如汉字)时出现问题,无需额外的工作或代码。你可以试试 changing the Console font to a TrueType font such as Consolas or Courier New. Or for UTF-32, look at the code samples here.
- 您的 xml 文件是没有 BOM 的 UTF8,如果这是静态的(不会更改),那么您最好在代码中指定它。您的 gist is using
Encoding.Default
but when I changed it toEncoding.UTF8
the Kanji string was correct. I looked at methods for detecting the encoding,但您需要决定 XML 文件是否会更改编码。 - 我在十六进制编辑器中查看了第一个
<literal>亜</literal>
,它是E4 BA 9C
,但是当我将字符粘贴到Visual Studio时,它只是E4 9C
。我相信BA
是 combining character。如果编码错误,您可能会看到亜
。如果你没有使用 TTF 字体,你会看到疯狂的字符。即使在我的系统上使用 Consolas,E4 9C
字符串显示一个带框的问号,但当我复制并粘贴时它是正确的字符。