Подтвердить что ты не робот

При сохранении 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()));

И вот вывод:

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

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

В основном, он делает файл xml и устанавливает кодировку в utf8, но когда он сохраняет его в stringwriter, он игнорирует мою кодировку и использует utf16. Однако при использовании потока памяти он использует utf8 (с дополнительными символами спецификации)

Почему это? Почему он не выполняет мою явную настройку кодировки utf-8?

Спасибо большое

4b9b3361

Ответ 1

Поскольку все, что вы делаете, это настройка XML-элемента, который говорит UTF-8, вы фактически не сохраняете его как 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, используйте StreamWriter, который обертывает MemoryStream.

Ответ 2

Из MSDN мы можем видеть...

Кодировка в TextWriter определяет выписанную кодировку (кодировка XmlDeclaration node заменяется кодировкой TextWriter). Если в TextWriter не было кодирования, XmlDocument сохраняется без атрибута кодирования.

Если вы хотите использовать кодировку из XmlDeclaration, вам нужно будет использовать поток для сохранения документа.

Ответ 3

Я использую следующий метод, он записывает его довольно и как 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));