How to Pretty Print XML from PowerShell, and output UTF, ANSI and other non-unicode formats

PowerShell has been taking more than its fair share of my time of late and I need redress the balance a bit – just not quite yet.

Powershell and redirection.

I’ve been working on my hyper-V library for codeplex and this has separate files for every command, and then to keep the start-up process for the module manageable these are merged together – I have a very short script to do this . All the constants from the top of the files get grouped together, at the top of the final file, but basically it is getting the files and outputting them to a destination using the > and >> operators . Then I got a mail from Ben who wanted to sign the scripts but found a problem if they saved as “Unicode BigEndian Text”. I hadn’t selected this, but that’s the default for text output from PowerShell. One can use Out-File –encoding ASCII, but that has another undesirable behaviour – it pads (or truncates) text to fit a given width. It turns out that – although the help files for Add-Content and Set-Content don’t mention it, both take –encoding  so > can be replaced with | Set-Content –encoding ASCII filename and  >> can be replaced with | Add-Content –encoding ASCII filename.

Pretty printing XML

Ben’s mail was rather timely because I had parked a problem with XML. I wrote about writing MAML Help files some while back and I’m still using InfoPath to do the job: the formatting is wantonly nasty. So I wanted to reformat the files they were vaguely readable, and went and found various articles about how to do it (I think I ended up adapting this code of James’s but I wish now I’d kept the link to be sure I’m assigning credit correctly)

function Format-XML `` {Param ([string]$xmlfile)   $Doc=New-Object system.xml.xmlDataDocument   $doc.Load((Resolve-Path $xmlfile))   `` $sw=New-Object system.io.stringwriter   `` $writer=New-Object system.xml.xmltextwriter($sw)   $writer.Formatting = [System.xml.formatting]::Indented   $doc.WriteContentTo($writer)   $sw.ToString() `` }

Of course I use > to redirect this to a file and it did not work if I used | clip and pasted it into notepad all was well. Eventually it dawned on me that the first line of the file was <?xml version="1.0" encoding="UTF-8" ?>

And of course I was creating unicode files so … | Set-Content –encoding UTF8 and it all works. So I had my  nicely format XML files providing help. And the next post will explain what it was all for.

Comments

  • Anonymous
    January 19, 2010
    Fantastic tip, thank you so much. I query Windows Mobile CSPs' a fair bit which outputs to an XML file. After I upgraded to Windows 7, the output of these files was one long continuous string of text which was not very easy on the eye. This function quickly structures the XML in a nice easy to read format. Cheers