При реализации размещенных здесь предложений у меня возникли проблемы с кодировкой текста. Кажется, кодировка XmlWriterSettings
игнорируется и всегда переопределяется кодировкой потока. При использовании StringBuilder
это всегда кодировка текста, используемая внутри C #, а именно UTF-16.
Итак, вот версия, которая поддерживает и другие кодировки.
ВАЖНОЕ ПРИМЕЧАНИЕ. Форматирование полностью игнорируется, если для объекта XMLDocument
свойство preserveWhitespace
включено при загрузке документа. Это поставило меня в тупик на некоторое время, поэтому не включайте его.
Мой окончательный код:
public static void SaveFormattedXml(XmlDocument doc, String outputPath, Encoding encoding)
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.IndentChars = "\t";
settings.NewLineChars = "\r\n";
settings.NewLineHandling = NewLineHandling.Replace;
using (MemoryStream memstream = new MemoryStream())
using (StreamWriter sr = new StreamWriter(memstream, encoding))
using (XmlWriter writer = XmlWriter.Create(sr, settings))
using (FileStream fileWriter = new FileStream(outputPath, FileMode.Create))
{
if (doc.ChildNodes.Count > 0 && doc.ChildNodes[0] is XmlProcessingInstruction)
doc.RemoveChild(doc.ChildNodes[0]);
// save xml to XmlWriter made on encoding-specified text writer
doc.Save(writer);
// Flush the streams (not sure if this is really needed for pure mem operations)
writer.Flush();
// Write the underlying stream of the XmlWriter to file.
fileWriter.Write(memstream.GetBuffer(), 0, (Int32)memstream.Length);
}
}
Это сохранит отформатированный xml на диск с заданной кодировкой текста.