Каков самый простой способ получить отступ XML с разрывами строк из XmlDocument?
когда я создаю XML с нуля с XmlDocument на OuterXml свойство уже имеет все красиво отступы с разрывами строк. Однако, если я позвоню LoadXml на некоторых очень "сжатых" XML (без разрывов строк или отступов), то вывод OuterXml останется. Так. ..
каков самый простой способ получить украшенный XML-вывод из экземпляра XmlDocument?
11 ответов:
основываясь на других ответах, я заглянул в
XmlTextWriterи придумал следующий вспомогательный метод:static public string Beautify(this XmlDocument doc) { StringBuilder sb = new StringBuilder(); XmlWriterSettings settings = new XmlWriterSettings { Indent = true, IndentChars = " ", NewLineChars = "\r\n", NewLineHandling = NewLineHandling.Replace }; using (XmlWriter writer = XmlWriter.Create(sb, settings)) { doc.Save(writer); } return sb.ToString(); }Это немного больше кода, чем я надеялся, но это работает просто замечательно.
в соответствии с Эрика Эрли - блог, это должно сделать это:
XmlDocument doc = new XmlDocument(); doc.LoadXml("<item><name>wrench</name></item>"); // Save the document to a file and auto-indent the output. using (XmlTextWriter writer = new XmlTextWriter("data.xml", null)) { writer.Formatting = Formatting.Indented; doc.Save(writer); }
или даже проще, если у вас есть доступ к LINQ
try { RequestPane.Text = System.Xml.Linq.XElement.Parse(RequestPane.Text).ToString(); } catch (System.Xml.XmlException xex) { displayException("Problem with formating text in Request Pane: ", xex); }
более короткая версия метода расширения
public static string ToIndentedString( this XmlDocument doc ) { var stringWriter = new StringWriter(new StringBuilder()); var xmlTextWriter = new XmlTextWriter(stringWriter) {Formatting = Formatting.Indented}; doc.Save( xmlTextWriter ); return stringWriter.ToString(); }
если выше украсить метод вызывается для
XmlDocument, содержащейXmlProcessingInstructionдочерний узел возникает следующее исключение:не удается написать объявление XML. Метод WriteStartDocument уже написал его.
Это моя измененная версия оригинала, чтобы избавиться от исключений:
private static string beautify( XmlDocument doc) { var sb = new StringBuilder(); var settings = new XmlWriterSettings { Indent = true, IndentChars = @" ", NewLineChars = Environment.NewLine, NewLineHandling = NewLineHandling.Replace, }; using (var writer = XmlWriter.Create(sb, settings)) { if (doc.ChildNodes[0] is XmlProcessingInstruction) { doc.RemoveChild(doc.ChildNodes[0]); } doc.Save(writer); return sb.ToString(); } }это работает для меня сейчас, вероятно, вам нужно будет сканировать все дочерние узлы для
XmlProcessingInstructionузел, а не только первый?
Обновление Апрель 2015:
так как у меня был еще один случай, когда кодировка была неправильной, я искал, как применить UTF-8 без спецификации. Я нашел этот блог и создал на его основе функцию:
private static string beautify(string xml) { var doc = new XmlDocument(); doc.LoadXml(xml); var settings = new XmlWriterSettings { Indent = true, IndentChars = "\t", NewLineChars = Environment.NewLine, NewLineHandling = NewLineHandling.Replace, Encoding = new UTF8Encoding(false) }; using (var ms = new MemoryStream()) using (var writer = XmlWriter.Create(ms, settings)) { doc.Save(writer); var xmlString = Encoding.UTF8.GetString(ms.ToArray()); return xmlString; } }
public static string FormatXml(string xml) { try { var doc = XDocument.Parse(xml); return doc.ToString(); } catch (Exception) { return xml; } }
простой способ заключается в использовании:
writer.WriteRaw(space_char);Как и этот пример кода, этот код является то, что я использовал для создания древовидного представления, как структура с помощью XMLWriter :
private void generateXML(string filename) { using (XmlWriter writer = XmlWriter.Create(filename)) { writer.WriteStartDocument(); //new line writer.WriteRaw("\n"); writer.WriteStartElement("treeitems"); //new line writer.WriteRaw("\n"); foreach (RootItem root in roots) { //indent writer.WriteRaw("\t"); writer.WriteStartElement("treeitem"); writer.WriteAttributeString("name", root.name); writer.WriteAttributeString("uri", root.uri); writer.WriteAttributeString("fontsize", root.fontsize); writer.WriteAttributeString("icon", root.icon); if (root.children.Count != 0) { foreach (ChildItem child in children) { //indent writer.WriteRaw("\t"); writer.WriteStartElement("treeitem"); writer.WriteAttributeString("name", child.name); writer.WriteAttributeString("uri", child.uri); writer.WriteAttributeString("fontsize", child.fontsize); writer.WriteAttributeString("icon", child.icon); writer.WriteEndElement(); //new line writer.WriteRaw("\n"); } } writer.WriteEndElement(); //new line writer.WriteRaw("\n"); } writer.WriteEndElement(); writer.WriteEndDocument(); } }таким образом, вы можете добавить разрывы табуляции или строки так, как вы обычно привыкли, т. е. \t или \n
при реализации предложений, опубликованных здесь, у меня возникли проблемы с кодировкой текста. Кажется, кодировка
XmlWriterSettingsигнорируется, и всегда переопределяется кодирование потока. При использованииStringBuilder, это всегда кодировка текста, используемая внутри C#, а именно UTF-16.Итак, вот версия, которая поддерживает и другие кодировки.
важное примечание: форматирование полностью игнорируется, если ваш
Если у вас есть строка XML, а не документ, готовый к использованию, вы можете сделать это следующим образом:
var xmlString = "<xml>...</xml>"; // Your original XML string that needs indenting. xmlString = this.PrettifyXml(xmlString); private string PrettifyXml(string xmlString) { var prettyXmlString = new StringBuilder(); var xmlDoc = new XmlDocument(); xmlDoc.LoadXml(xmlString); var xmlSettings = new XmlWriterSettings() { Indent = true, IndentChars = " ", NewLineChars = "\r\n", NewLineHandling = NewLineHandling.Replace }; using (XmlWriter writer = XmlWriter.Create(prettyXmlString, xmlSettings)) { xmlDoc.Save(writer); } return prettyXmlString.ToString(); }
более упрощенный подход, основанный на принятом ответе:
static public string Beautify(this XmlDocument doc) { StringBuilder sb = new StringBuilder(); XmlWriterSettings settings = new XmlWriterSettings { Indent = true }; using (XmlWriter writer = XmlWriter.Create(sb, settings)) { doc.Save(writer); } return sb.ToString(); }установка новой строки не требуется. Отступы также имеют два пробела по умолчанию, поэтому я предпочел не устанавливать его.
Comments