Friday, November 5, 2010

Transforming an XML file with an XSLT in PowerShell

This code will transform an XML file with an XSLT file and save the resulting file to disk:

$xslt = new-object system.xml.xsl.xslcompiledtransform
$xslt.load('transform.xslt')
$xslt.Transform('input.xml', 'output.xml')

3 comments:

  1. I'm trying your example, along with several others, under Windows 8.1 and I consistently get the following error. Has this call changed in the latest revision of code? I must have gone through about 10 various example code bodies and they all result in the exact same error it appears. I've Googled this error for hours and have found references noting that I can't use XSL 2.0 and other references to how the XSL might have includes or imports... but none of those apply to my simple example. Another post notes that it might be caused when running the example repeatedly as it should only be compiled once, but there wasn't any clear note regarding how to avoid compiling it more than once if the xslcompiledtransform object clearly has to be declared in order to be used. Any help would be appreciated. Apparently I am missing something basic here.

    CODE:
    ------------------
    $xslt = new-object system.xml.xsl.xslcompiledtransform
    $xslt.load('C:\Users\RJLyders\SkyDrive\Documents\ps1\cdcatalog.xsl')
    $xslt.Transform('C:\Users\RJLyders\SkyDrive\Documents\ps1\cdcatalog.xml', 'C:\Users\RJLyders\SkyDrive\Documents\ps1\cdcatalog-out.xml')

    ERRORS:
    -----------------------
    Exception calling "Load" with "1" argument(s): "XSLT compile error."
    At C:\Users\Jim\SkyDrive\Documents\ps1\xlst_transform.ps1:2 char:1
    + $xslt.load('C:\Users\Jim\SkyDrive\Documents\ps1\cdcatalog.xsl')
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : XslLoadException

    Exception calling "Transform" with "2" argument(s): "No stylesheet was loaded."
    At C:\Users\Jim\SkyDrive\Documents\ps1\xlst_transform.ps1:3 char:1
    + $xslt.Transform('C:\Users\Jim\SkyDrive\Documents\ps1\cdcatalog.xml', 'C:\Us ...
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : InvalidOperationException

    ReplyDelete
    Replies
    1. Interesting. I just tried a basic transform on Windows 8.1 and it worked as expected. This is what I did:

      1. Downloaded the XSLT and XML input data from this StackOverflow question (there's nothing special about this question - it just has a simple transform and input): https://stackoverflow.com/questions/4943611/simple-xslt-template
      2. Ran the commands above - but with absolute paths like you have because the process's current working directory was different from the PowerShell current working directory

      The transformation worked as expected.

      Are you able to post the XSLT somewhere? Note that .NET unfortunately doesn't support XSLT 2.0, so it may be having trouble parsing your XSLT.

      Delete
    2. Ignore my comment on XSLT 2.0 - I re-read yours and notice that you're already aware of these issues.

      I also tried running my example repeatedly, and there was no problem:

      1..100 | % { $xslt = new-object system.xml.xsl.xslcompiledtransform;$xslt.load('c:\temp\xsl\transform.xslt');$xslt.Transform('c:\temp\xsl\input.xml', 'c:\temp\xsl\output.xml') }

      I also tried:

      $xslt = new-object system.xml.xsl.xslcompiledtransform; 1..100 | % { $xslt.load('c:\temp\xsl\transform.xslt');$xslt.Transform('c:\temp\xsl\input.xml', 'c:\temp\xsl\output.xml') }

      Again, no issues.

      Delete