【问题标题】:Unity C# System.Xml.Linq - XDocument changes the encoding in a XML declarationUnity C# System.Xml.Linq - XDocument 更改 XML 声明中的编码
【发布时间】:2020-02-14 19:01:08
【问题描述】:

我正在尝试在 C#(特别是 Unity 2017.4.33f1)中修改一个 utf-16 编码的 XML 文件。

编辑:原来原始文件指定了 utf-8 编码!

我正在使用此代码加载文档:

using (FileStream fileStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
{
   _Document = XDocument.Load(fileStream);
}

从调试器检查对象时,XDocument 似乎已将文档的声明加载为 UTF-8,即使原始文档指定 UTF-16。

为什么会这样?有什么方法可以阻止 XDocument 在加载文件时更改编码?

【问题讨论】:

  • 加载到内存时,内容始终为 UTF-16。声明的编码仅在序列化到存储时才起作用。并且完全可以在 XML 标头中声明一种编码,然后将 XML 保存到具有另一种编码的文件中(您不应该这样做,但可以)。您的文件实际包含什么编码?
  • @GSerg 啊!你是对的。原始文件确实是 utf-8 编码的。 XDocument 通过 ToString 报告 UTF-16 编码的事实令人困惑。
  • @jdweng 很久以前,您有一个无效的 XML 文件,您不知道出了什么问题以及如何正确修复它。相反,您确定了.NET is broken,并提出了“修复”。如果 XML 声明和 file encoding 确实是 utf-16,则将 XML 保存为 utf-16 是完全可以的。我强烈建议您访问这两个链接,而不是传递做错事的建议。
  • 嗯,XML 内容是一段文本的集合,每段文本都是一个string,并且总是采用 UTF-16 格式。我不愿意发布答案,因为我不知道确定会发生什么以及为什么,它是否已记录在案或是否是错误,以及它是否可靠或将来可能会发生变化。例如。我所指的答案解释说,在文件和 XML 声明中使用不同的编码是一个致命错误,但 .NET 解析器 显然 仍然选择加载它,并且 显然,滑入了修改后的声明节点。如果这是正确和稳定的行为,我无法评论。
  • @GSerg 好的,这很公平。我现在提供一个答案。谢谢你的意见!它帮助很大。

标签: c# xml system.xml


【解决方案1】:

tl;dr:使用 XDocument.Save() 及其重载

根据问题的 cmets 中的讨论,这似乎是 Unity 2017.4.33f1 的 .NET 实现的行为:

XDocument.ToString() 会将文档编码为 UTF-16 并将该 XML 输出为字符串 并将文档内编码声明更改为 utf-16,而不管在对象/源文件.NET strings are always UTF-16 encoded,所以这可能是这种行为的来源。 .NET 正在输出有效的 XML,但不是准确反映 XDocument 对象 ToString() 被调用的 XML。这意味着像这样的代码:

XDocument doc = XDocument.Load(path); 
System.Encoding enc = System.Encoding.GetEncoding(doc.Declaration.Encoding);
System.IO.File.WriteAllText(path, doc.ToString(), enc);

如果文档最初不是 UTF-16 编码,则将写入无效的 XML。

XDocument.Save(string path) 遵循XDocument.Declaration 中指定的编码,并将使用该编码保存文件。

【讨论】:

    猜你喜欢
    • 2011-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-15
    • 2016-11-06
    • 1970-01-01
    • 2014-10-18
    • 1970-01-01
    相关资源
    最近更新 更多