【问题标题】:why does the Xdocument give me a utf16 declaration?为什么 Xdocument 会给我一个 utf16 声明?
【发布时间】:2011-03-09 15:56:28
【问题描述】:

我正在创建这样的 XDocument:

XDocument doc = new XDocument(
new XDeclaration("1.0", "utf-8", "yes"));

当我像这样 (doc.Save(@"c:\tijd\file2.xml");) 保存文档时,我得到了这个:

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

没关系。

但我想将内容作为xml返回,我找到了以下代码:

 var wr = new StringWriter(); 
            doc.Save(wr); 
            string s = (wr.GetStringBuilder().ToString());

此代码有效,但字符串 's' 以此开头:

<?xml version="1.0" encoding="utf-16" standalone="yes"?>

所以它从 utf8 变成了 utf16,这不是我想要的,因为现在我无法在 Internet Explorer 中阅读它。

有没有办法防止这种行为?

【问题讨论】:

  • 这里有一个大红旗,字符串编写器确实包含一个 utf-16 编码的字符串。即使您覆盖 Encoding 属性。这是如何从 StringWriter 进入 IE 的?
  • 好问题。我用 File.WriteAllText 将字符串 's' 保存到一个文件中,然后用 IE 打开它。在我的问题中没有明确说明...
  • 对,File.WriteAllText() 调用是真正 确定编码的调用。默认为 utf-8,除非您使用采用编码的重载。

标签: c# linq-to-xml


【解决方案1】:

StringWriter 宣传自己使用 UTF-16。不过很容易解决:

public class Utf8StringWriter : StringWriter
{
    public override Encoding Encoding { get { return Encoding.UTF8; } }
}

在您的特定情况下应该足够了。一个更全面的实现将:

  • 具有与StringWriter 中的构造匹配的构造函数
  • 也允许在构造函数中指定编码

【讨论】:

  • 嗯,好吧,所以 StringWriter 使它成为 UTF-16。我总是试图理解编码的东西,但它似乎并没有坚持下去。听起来像 stringwriter 这样的 UTF-16 对象创建一个 UTF-16 字符串是合乎逻辑的,但让我印象深刻的是它也改变了 XML 文件中的声明。不认为这是由 StringWriter 引起的,因为当我在 XDocument 之前使用 XmlDocument 时,我也一直在努力使用 UTF-16,所以我认为这只是一个 .Net 习惯或其他东西。所以谢谢你的回答!
  • @Michel:基本上 Save 方法询问作者使用什么编码,以便它使用任何合适的编码。有点乱,我同意...
  • 我知道这是一个旧线程,但是对于使用此解决方案的其他人,请记住当您新建需要使用的对象时:var wr = new Utf8StringWriter ();
  • @SDanks:只要使用TextWriter wr = new Utf8StringWriter(); 就可以了。不清楚您要强调什么 - 这没有什么特别奇怪的。
【解决方案2】:

使用继承很好的回答,只记得重写初始化器

   public class Utf8StringWriter : StringWriter
    {
        public Utf8StringWriter(StringBuilder sb) : base (sb)
        {
        }
        public override Encoding Encoding { get { return Encoding.UTF8; } }
    }

【讨论】:

    【解决方案3】:

    您需要将 StreamWriter.Encoding 设置为使用 UTF-8 而不是 Unicode (UTF-16)

    因为它不是 StreamWriter,所以这个答案只留给后代。

    【讨论】:

    • 这里没有涉及到 StreamWriter。只有一个 StringWriter,你不能以编程方式设置它的编码 - 你必须通过继承来做到这一点:(
    • 哇,是的,我完全误读了正在使用的内容。继承就是了。
    猜你喜欢
    • 1970-01-01
    • 2013-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-19
    • 2020-04-25
    • 2013-11-14
    • 1970-01-01
    相关资源
    最近更新 更多