Programmatically format XML indented, just like Visual Studio AutoFormat

I did not find a way to use .NET XmlWriter and its associated XmlWriterSettings to format indented XML strings exactly as Visual Studio does with its automatic formatting command (Ctrl-E Ctrl-D or, depending on the keyboard, Ctrl-K Ctrl-D).

I would like to do this because I usually automatically formatted all my files in VS, both in code and in .config files. I have an installer application that updates .config files and I would like the actual differences to be changed instead of the whole document.

I did not study all the different formatting options for the automatic format, but I like that each XML attribute is on a separate line, the first on the same line as the opening tag, and the subsequent ones queued with the first, like this:

<asset assetId="12345" bucket="default" owner="nobody"> <file path="\\localhost\share\assetA.mov"/> <metadata metadataId="23456" key="asset_type" value="video"/> </asset> 

I tried formatting using the XmlWriterSettings properties "NewLineHandling = NewLineHandling.None" and "NewLineOnAttributes = true", but this puts the first attribute below the opening tag, and all attributes have the same indentation, regardless of # characters in the element name, for example:

 <asset assetId="12345" bucket="default" owner="nobody"> <file path="\\localhost\share\assetA.mov" /> <metadata metadataId="23456" key="asset_type" value="video" /> </asset> 

Note that the standard XmlWriter also closes attribute elements with "/"> "(extra space before the slash), which I don’t like, but not sure if this XML standard. I would think that Visual Studio uses the same options APIs that are easily accessible by developers, but I have not found these magic settings yet.Anyway, here is my format method:

 public static string FormatXml( string xmlString, bool indented ) { using ( TextReader textReader = new StringReader( xmlString ) ) using ( XmlReader xmlReader = new XmlTextReader( textReader ) ) { using ( TextWriter textWriter = new StringWriter() ) { var settings = new XmlWriterSettings(); if ( indented ) { settings.Indent = true; settings.IndentChars = " "; settings.NewLineOnAttributes = true; settings.NewLineHandling = NewLineHandling.None; } using ( var xmlWriter = XmlWriter.Create( textWriter, settings ) ) { while ( xmlReader.Read() ) xmlWriter.WriteNode( xmlReader, false ); } return textWriter.ToString(); } } } 
+6
xml formatting visual-studio autoformatting
source share
3 answers

I misunderstood this question. Actually, I don’t know if there is a way to align the attributes as you showed. You can try to implement it yourself, something like this:

  public static string FormatXml(string xmlString, bool indented) { using (TextReader textReader = new StringReader(xmlString)) using (XmlReader xmlReader = new XmlTextReader(textReader)) { using (TextWriter textWriter = new StringWriter()) { string indent = ""; string attributeIndent = ""; while (xmlReader.Read()) { if (xmlReader.NodeType == XmlNodeType.Element) { attributeIndent = ""; string element = xmlReader.Name; textWriter.Write("{0}<{1}", indent, element); if (!xmlReader.HasAttributes) textWriter.WriteLine(">"); else { int actual = 1; while (xmlReader.MoveToNextAttribute()) { string content = String.Format("{0} {1}={2}", attributeIndent, xmlReader.Name, xmlReader.Value); if (actual != xmlReader.AttributeCount) textWriter.WriteLine(content); else textWriter.Write(content); if (string.IsNullOrEmpty(attributeIndent)) attributeIndent = indent + Enumerable.Repeat<string>(" ", element.Length + 1).Aggregate((a, b) => a + b); actual++; } xmlReader.MoveToElement(); textWriter.WriteLine(">"); attributeIndent = ""; } if (!xmlReader.IsEmptyElement) { indent += " "; textWriter.WriteLine(">"); } else textWriter.WriteLine("/>"); } else if (xmlReader.NodeType == XmlNodeType.EndElement) { indent = indent.Substring(0, indent.Length - 2); textWriter.WriteLine("{0}</{1}>", indent, xmlReader.Name); } else if (xmlReader.NodeType == XmlNodeType.Text) { textWriter.WriteLine(xmlReader.Value); } } return textWriter.ToString(); } } } 
+1
source share

See the answer here: Is there a stylesheet or a Windows command-line tool for managed XML formatting, in particular, for adding attributes one line at a time?

It is close, but the main difference at first glance is that the first attribute is on a new line, while in Visual Studio it remains on the same line as the name of the element.

0
source share

I think the quotes are invalid xml, which may give the reader / writer some heartburn. Other than that, why don't you just say that your diff application ignores spaces?

0
source share

All Articles