保存XmlDocument时,它会忽略XmlDeclaration(UTF8)中的编码并使用UTF16

我有以下代码:

var doc = new XmlDocument(); XmlDeclaration xmlDeclaration = doc.CreateXmlDeclaration("1.0", "UTF-8", null); doc.AppendChild(xmlDeclaration); XmlElement root = doc.CreateElement("myRoot"); doc.AppendChild(root); root.InnerText = "myInnerText"; StringWriter sw = new StringWriter(); doc.Save(sw); Console.WriteLine(sw.ToString()); Console.WriteLine(); MemoryStream ms = new MemoryStream(); doc.Save(ms); Console.WriteLine(Encoding.ASCII.GetString(ms.ToArray())); 

这是输出:

  myInnerText ??? myInnerText 

基本上它的作用是创建一个xml文件,并将编码设置为utf8,但是当它将它保存到字符串编写器时,它会忽略我的编码并使用utf16。 但是,在使用内存流时,它使用utf8(带有额外的BOM字符)

为什么是这样? 为什么不尊重我对utf-8的显式编码设置?

非常感谢

因为您所做的只是设置一个表示它是UTF-8的XML元素,所以您实际上并没有将其保存为UTF-8。 您需要将输出流设置为使用UTF-8,如下所示:

 var doc = new XmlDocument(); XmlElement root = doc.CreateElement("myRoot"); doc.AppendChild(root); root.InnerText = "myInnerText"; using(TextWriter sw = new StreamWriter("C:\\output.txt", false, Encoding.UTF8)) //Set encoding { doc.Save(sw); } 

一旦这样做,您甚至不必添加XML声明。 它自己解决了这个问题。 如果要将其保存到MemoryStream,请使用包装MemoryStream的StreamWriter。

我使用以下方法,它写得很漂亮, 作为UTF-8

 public static string Beautify(XmlDocument doc) { string xmlString = null; using (MemoryStream ms = new MemoryStream()) { XmlWriterSettings settings = new XmlWriterSettings { Encoding = new UTF8Encoding(false), Indent = true, IndentChars = " ", NewLineChars = "\r\n", NewLineHandling = NewLineHandling.Replace }; using (XmlWriter writer = XmlWriter.Create(ms, settings)) { doc.Save(writer); } xmlString = Encoding.UTF8.GetString(ms.ToArray()); } return xmlString; } 

称之为:

 File.WriteAllText(fileName, Utilities.Beautify(xmlDocument)); 

从MSDN我们可以看到……

TextWriter上的编码确定写出的编码(XmlDeclaration节点的编码由TextWriter的编码替换)。 如果TextWriter上没有指定编码,则保存XmlDocument而不使用编码属性。

如果要使用XmlDeclaration中的编码,则需要使用流来保存文档。