Home > Uncategorized > Powershell, XML and XSLT as one big happy family

Powershell, XML and XSLT as one big happy family

I was scanning through my blog feeds today when I stumbled upon this video tutorial, showing how to use Visual Studio for XSLT development. I was impressed by the good support for XSLT and specifically by the great debugging capabilities. I wanted to try it out so I needed a problem that could be solved using XSLT. One thing that came to my mind was to transform the xml output from the ConvertTo-XML powershell commandlet. Given the following script:

$o = new-object psobject -property @{ Name=‘Peter’; Age=12 }
$o2 = new-object psobject -property @{ Name=‘Samuel’; Age=20 }
$o, $o2 | ConvertTo-Xml -As String

the resulting xml will be:

<?xml version="1.0"?>


  <Object Type="System.Management.Automation.PSCustomObject">

    <Property Name="Name" Type="System.String">Peter</Property>

    <Property Name="Age" Type="System.Int32">12</Property>


  <Object Type="System.Management.Automation.PSCustomObject">

    <Property Name="Name" Type="System.String">Samuel</Property>

    <Property Name="Age" Type="System.Int32">20</Property>



This xml document is not very convenient for powershell scripting. For example, accessing the age of Samuel would require the following line, assume that the xml document was stored in $data:


Not that obvious, indeed. Using Visual Studio I was able to come up with the following XLST transform:

<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"


  <xsl:output method="xml" indent="yes"/>


  <xsl:template match="@* | node()">


      <xsl:apply-templates select="@* | node()"/>




  <!– ref: http://www.dpawson.co.uk/xsl/sect2/N7240.html –>

  <xsl:template name="substring-after-last">

    <xsl:param name="string" />

    <xsl:param name="delimiter" />


      <xsl:when test="contains($string, $delimiter)">

        <xsl:call-template name="substring-after-last">

          <xsl:with-param name="string" select="substring-after($string, $delimiter)" />

          <xsl:with-param name="delimiter" select="$delimiter" />




        <xsl:value-of select="$string" />





  <xsl:template match="Object">

    <xsl:variable name="shortTypeName">

      <xsl:call-template name="substring-after-last">

        <xsl:with-param name="string" select="@Type" />

        <xsl:with-param name="delimiter" select="‘.’" />



    <xsl:element name="{$shortTypeName}">

      <xsl:apply-templates select="node()"/>




  <xsl:template match="Property">

    <xsl:element name="{@Name}">

      <xsl:value-of select="./text()"/>






When applied to the xml document above it produces the following:

<?xml version="1.0" encoding="utf-8"?>











This xml document allows a much more natural navigation. Samuels age can now be retrieved using:


Categories: Uncategorized
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: