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.
Here's a PowerShell script to do it. It takes the following input:
<?xml version="1.0" encoding="utf-8"?>
<Node>
<ChildNode value1="5" value2="6" value3="happy" />
</Node>
...and produces this as output:
<?xml version="1.0" encoding="utf-8"?>
<Node>
<ChildNode
value1="5"
value2="6"
value3="happy" />
</Node>
Here you go:
param(
[string] $inputFile = $(throw "Please enter an input file name"),
[string] $outputFile = $(throw "Please supply an output file name")
)
$data = [xml](Get-Content $inputFile)
$xws = new-object System.Xml.XmlWriterSettings
$xws.Indent = $true
$xws.IndentChars = " "
$xws.NewLineOnAttributes = $true
$data.Save([Xml.XmlWriter]::Create($outputFile, $xws))
Take that script, save it as C:\formatxml.ps1. Then, from a PowerShell prompt type the following:
C:\formatxml.ps1 C:\Path\To\UglyFile.xml C:\Path\To\NeatAndTidyFile.xml
This script is basically just using the .NET framework so you could very easily migrate this into a C# application.
NOTE: If you have not run scripts from PowerShell before, you will have to execute the following command at an elevated PowerShell prompt before you will be able to execute the script:
Set-ExecutionPolicy RemoteSigned
You only have to do this one time though.
I hope that's useful to you.
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();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With