Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 保存XmlDocument时,它会忽略XmlDeclaration(UTF8)中的编码,并使用UTF16_C#_Xml - Fatal编程技术网

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

C# 保存XmlDocument时,它会忽略XmlDeclaration(UTF8)中的编码,并使用UTF16,c#,xml,C#,Xml,我有以下代码: 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 = "myInnerTex

我有以下代码:

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()));
以下是输出:

<?xml version="1.0" encoding="utf-16"?>
<myRoot>myInnerText</myRoot>

???<?xml version="1.0" encoding="UTF-8"?>
<myRoot>myInnerText</myRoot>

myInnerText
???
myInnerText
基本上,它所做的是生成一个xml文件,并将编码设置为utf8,但当它将其保存到stringwriter时,它会忽略我的编码并使用utf16。然而,当使用内存流时,它使用utf8(带有额外的BOM字符)

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

非常感谢

从我们可以看到

TextWriter上的编码确定写入的编码(XmlDeclaration节点的编码替换为TextWriter的编码)。如果TextWriter上没有指定编码,则保存XmlDocument时不带编码属性


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

因为您所做的只是设置一个表示为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));

那么基本上你是说C#在将文档保存到textwriter时忽略了xmldeclaration?好了,现在有道理了。Thankso xml编写器将覆盖您放入xml声明中的任何内容,具体取决于它保存到的对象,即流、文本编写器或文件。就xml声明而言,它只是一个元素(尽管很奇怪)。它声明如何保存,而不是如何保存。这就是为什么当它被保存时,它会为你放在那里。谢谢,它很有效。。但是,如果您在Windows中,默认编码UTF8将放置在文件的开头,BOM标记和一些系统会拒绝使用UTF-8-BOM的文件。danielwertheim在这篇伟大的文章中解释了在Windows中如何编写UTF-8,以及如何在没有BOM的情况下编写UTF-8。只是好奇,您是否尝试在编码中指定null/string.empty,然后查看??如果我这样做,stringwriter仍然是utf16,而memorystream在其声明中没有编码。例如。看起来是这样的: