xmlpretty-printxml-formatting

Is there a stylesheet or Windows commandline tool for controllable XML formatting, specifically putting attributes one-per-line?


I am searching for an XSLT or command-line tool (or C# code that can be made into a command-line tool, etc) for Windows that will do XML pretty-printing. Specifically, I want one that has the ability to put attributes one-to-a-line, something like:

<Node>
   <ChildNode 
      value1='5'
      value2='6'
      value3='happy' />
</Node>

It doesn't have to be EXACTLY like that, but I want to use it for an XML file that has nodes with dozens of attributes and spreading them across multiple lines makes them easier to read, edit, and text-diff.

NOTE: I think my preferred solution is an XSLT sheet I can pass through a C# method, though a Windows command-line tool is good too.


Solution

  • Here's a small C# sample, which can be used directly by your code, or built into an exe and called at the comand-line as "myexe from.xml to.xml":

        using System.Xml;
    
        static void Main(string[] args)
        {
            XmlWriterSettings settings = new XmlWriterSettings {
                NewLineHandling = NewLineHandling.Entitize,
                NewLineOnAttributes = true, Indent = true, IndentChars = "  ",
                NewLineChars = Environment.NewLine
            };
    
            using (XmlReader reader = XmlReader.Create(args[0]))
            using (XmlWriter writer = XmlWriter.Create(args[1], settings)) {
                writer.WriteNode(reader, false);
                writer.Close();
            }
        }
    

    Sample input:

    <Node><ChildNode value1='5' value2='6' value3='happy' /></Node>
    

    Sample output (note you can remove the <?xml ... with settings.OmitXmlDeclaration):

    <?xml version="1.0" encoding="utf-8"?>
    <Node>
      <ChildNode
        value1="5"
        value2="6"
        value3="happy" />
    </Node>
    

    Note that if you want a string rather than write to a file, just swap with StringBuilder:

    StringBuilder sb = new StringBuilder();
    using (XmlReader reader = XmlReader.Create(new StringReader(oldXml)))
    using (XmlWriter writer = XmlWriter.Create(sb, settings)) {
        writer.WriteNode(reader, false);
        writer.Close();
    }
    string newXml = sb.ToString();