【问题标题】:XmlWriter outputs unexpected encoding when printing to console打印到控制台时 XmlWriter 输出意外编码
【发布时间】:2020-05-31 13:51:35
【问题描述】:

在学习 C# XmlWriter 课程时,我遇到了一些奇怪的行为。输出到文件时,它按预期使用 UTF-8,但输出到控制台时,它使用我的系统代码页 (862) 而不是 UTF-8。我知道控制台不支持 UTF-8,所以我想知道如果流是控制台,XmlWriter 是否默认为系统代码页?

重现行为的代码:

using System;
using System.Xml;

namespace xmlwriterTest
{
    class Program
    {
        static void Main(string[] args)
        {
            var settings = new XmlWriterSettings
            {
                Indent = true
            };

            using (XmlWriter writer = XmlWriter.Create(Console.Out, settings))
            {
                writer.WriteStartDocument();
                writer.WriteStartElement("users");

                writer.WriteStartElement("user");
                writer.WriteAttributeString("age", "42");
                writer.WriteString("John Doe");
                writer.WriteEndElement();

                writer.WriteStartElement("user");
                writer.WriteAttributeString("age", "39");
                writer.WriteString("Jane Doe");

                writer.WriteEndDocument();
                writer.Close();
                Console.WriteLine("\n\n");
            }
        }
    }
}

预期输出:

<?xml version="1.0" encoding="utf-8"?>

实际输出:

<?xml version="1.0" encoding="Codepage - 862"?>

编辑 我的问题不是如何在控制台中实现预期的输出。这就是为什么首先会发生这种情况

【问题讨论】:

  • 如何通过将Encoding 属性覆盖到UTF8 来创建一个使用StringBuilder 的自定义StringWriter,并在控制台中输出这个代表xml 的字符串生成器。
  • 使用 MemoryStream 作为 Stream 输出:它不会妨碍您。如果您使用 StringWriter,编码将始终为 UTF-16,无论您指定为 XmlWriterSettings.Encoding 属性值(如果您想确保输出中没有 BOM,则应为 Encoding = Encoding.UTF8new UTF8Encoding(false) )。

标签: c# xmlwriter


【解决方案1】:

根据评论更新

首先为什么会发生这种情况:因为Console.Out 的默认Encoding 不是UTF-8,所以我正在做这样的测试:

1.1 - 默认Encoding

TextWriter textWriter = Console.Out;

Console.WriteLine(textWriter.Encoding.BodyName);

1.2 - 结果:

ibm850

2.1 - 自定义 EncodingConsole.Out

Console.OutputEncoding = Encoding.UTF8;
TextWriter textWriter = Console.Out;

Console.WriteLine(textWriter.Encoding.BodyName);

2.2 - 结果:

utf-8

整个代码:

XmlWriterSettings settings = new XmlWriterSettings
{
    Indent = true
};

Console.OutputEncoding = Encoding.UTF8;

using (XmlWriter writer = XmlWriter.Create(Console.Out, settings))
{
    writer.WriteStartDocument();
    writer.WriteStartElement("users");

    writer.WriteStartElement("user");
    writer.WriteAttributeString("age", "42");
    writer.WriteString("John Doe");
    writer.WriteEndElement();

    writer.WriteStartElement("user");
    writer.WriteAttributeString("age", "39");
    writer.WriteString("Jane Doe");

    writer.WriteEndDocument();
    writer.Close();

    Console.WriteLine();
}

结果

<?xml version="1.0" encoding="utf-8"?>
<users>
  <user age="42">John Doe</user>
  <user age="39">Jane Doe</user>
</users>

旧代码

您可以使用StringBuilder覆盖 Encoding 属性创建自定义StringWriter,例如:

1 - 自定义类:

public class EncodedStringWriter : StringWriter
{
    public EncodedStringWriter(StringBuilder sb, Encoding encoding)
        : base(sb)
    {
        _Encoding = encoding;
    }

    private readonly Encoding _Encoding;

    public override Encoding Encoding => _Encoding;
}

2 - 使用 custom stringWriter 构造 XML:

StringBuilder sb = new StringBuilder();
EncodedStringWriter stringWriter = new EncodedStringWriter(sb, Encoding.UTF8);

XmlWriterSettings settings = new XmlWriterSettings
{
    Indent = true
};

using (XmlWriter writer = XmlWriter.Create(stringWriter, settings))
{
    writer.WriteStartDocument();
    writer.WriteStartElement("users");

    writer.WriteStartElement("user");
    writer.WriteAttributeString("age", "42");
    writer.WriteString("John Doe");
    writer.WriteEndElement();

    writer.WriteStartElement("user");
    writer.WriteAttributeString("age", "39");
    writer.WriteString("Jane Doe");

    writer.WriteEndDocument();
    writer.Close();

    Console.WriteLine(sb.ToString());
}

结果

<?xml version="1.0" encoding="utf-8"?>
<users>
  <user age="42">John Doe</user>
  <user age="39">Jane Doe</user>
</users>

希望对您有所帮助。

【讨论】:

  • 感谢您的尝试。我认为您误解了我的问题,我对其进行了编辑以进行澄清
  • @medic17 不客气,我正在添加一些解释,希望对您有所帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-13
  • 1970-01-01
  • 2021-06-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多