При сохранении 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?
Спасибо большое
Ответы
Ответ 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));