Applying an Xsl transform in PowerShell

I recently worked on a project that required an Xsl stylesheet be applied to an encoded Xml data set. I wanted to avoid the use of external files or executables and was able to leverage the dotnet XmlWriter and XslCompiledTransform classes to accomplish this task.

The runbook accepts two parameters, $Xml an Xml object containing the encoded Xml data, and $Xslt an Xml object containing the Xsl stylesheet used in the transform.

First we create an XmlWriterSettings object and configure the options required for our scenario.

$XmlWriterSettings = New-Object System.Xml.XmlWriterSettings;
$XmlWriterSettings.Indent = $True
$XmlWriterSettings.OmitXmlDeclaration = $True
$XmlWriterSettings.ConformanceLevel = "Fragment"

Next we create an empty XML object to receive the output from the transform then utilize it and our XmlWriterSettings to create an XmlWriter object.

$Output = [Xml]""
$XmlWriter = [System.Xml.XmlWriter]::Create($Output.CreateNavigator().AppendChild(),$XmlWriterSettings)

Now we can create the XslCompiledTransform object, load our style sheet, and finally apply the transform using our encoded Xml data set and the XmlWriter object we created earlier.

$XslTransform = New-Object System.Xml.Xsl.XslCompiledTransform;
$XslTransform.Load($Xslt)
$XslTransform.Transform($Xml,$XmlWriter)
$XmlWriter.Close()

Here is the completed runbook.

# $Xml is the raw xml data that needs to be transformed.
# $Xslt is the Xsl template you will be applying.
Param (
    [Parameter(Mandatory=$True)][Xml]$Xml,
    [Parameter(Mandatory=$True)][Xml]$Xslt
    )

# Prepare XML writer settings for transform
Write-Verbose -Message "Configuring Xml writer settings"
$XmlWriterSettings = New-Object System.Xml.XmlWriterSettings;
$XmlWriterSettings.Indent = $True
$XmlWriterSettings.OmitXmlDeclaration = $True
$XmlWriterSettings.ConformanceLevel = "Fragment"

# Create XML writer for use during the transform
Write-Verbose -Message "Creating Xml writer"
$Output = [Xml]""
$XmlWriter = [System.Xml.XmlWriter]::Create($Output.CreateNavigator().AppendChild(),$XmlWriterSettings)


# Create XSL transform object and load template
Write-Verbose -Message "Creating XslcompiledTransform object"
$XslTransform = New-Object System.Xml.Xsl.XslCompiledTransform;
$XslTransform.Load($Xslt)

# Run transform 
Write-Verbose -Message "Applying transform to Xml object"
$XslTransform.Transform($Xml,$XmlWriter)
$XmlWriter.Close()

Return $Output