2

I'm trying to clean XML Files with an XSL Transformation. When I'm applying my XSL directly to my XML File, it works fine. But now I want to clean every XML File I have in a directory. I've tried to create a PowerShell script, to load and transform XML Files.

Here is my code :

$dir = "C:\MyDirectory"
$XSLFileName = "XSLTFile.xsl"
$XSLFileInput = $dir + $XSLFileName

$XMLFileName = "Input.xml"
$XMLInputFile = $dir + $XMLFileName
$OutputFileName = "Output.xml"
$XMLOutputFile = $dir + $OutputFileName

cd $dir 

$XSLInputElement = New-Object System.Xml.Xsl.XslCompiledTransform;
$XSLInputElement.Load($XSLFileInput)

$XMLInputDoc = Get-Content -Path $XMLInputFile

$reader = [System.Xml.XmlReader]::Create($XMLInputFile)
$writer = [System.Xml.XmlTextWriter]::Create($XMLOutputFile)

$XSLInputElement.Transform($XMLInputDoc, $writer)

I've been threw some docs and SO subjects to find how to use the Transform() method, but I haven't found how to deal with this error :

Exception calling "Transform" with "2" argument(s): "Caractères non conformes dans le chemin d'accès."
At C:\ScirptsDirs\StackOverFlowTransformExample.ps1:20 char:1
+ $XSLInputElement.Transform($XMLInputDoc, $writter)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ArgumentException

Note : "Caractères non conformes dans le chemin d'accès." means : Invalid symbol found in the access path.

What I want to do is to clean my XML File, and to create an other XML File but with the XSL Transformation applied to it.

EDIT : I've also tried this way, as Martin said :

$XSLInputElement.Transform($XMLInputFile, $XMLOutputFile)

But this time, I have thee following error :

Exception calling "Transform" with "2" argument(s): "Execution of the 'document()' function was prohibited. Use the XsltSettings.EnableDocumentFunction property to enable it. An error occurred at  D:\MyDirectory\XSLTFile.xsl(220,3)."
At C:\ScirptsDirs\StackOverFlowTransformExample.ps1:20 char:1
+ $XSLInputElement.Transform($XMLInputFile, $XMLOutputFile)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : XslTransformException

2 Answers 2

3

If you have the input and output file name respectively path as a string then simply use $XSLInputElement.Transform($XMLInputFile, $XMLOutputFile).

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks Martin, but it's not working, i've tried this way, and I have an other error. I've edited my question so that you will be able to see the other error raised when I try your with your method.
Well, that error suggests that the Transform call with the arguments as suggested is working, only that the XSLT stylesheet you use calls the document function, so that you first need to make sure you use $XsltSettings = New-Object System.Xml.Xsl.XsltSettings(true, false); and $XSLInputElement = New-Object System.Xml.Xsl.XslCompiledTransform; $XSLInputElement.Load($XSLFileInput, $XsltSettings, New-Object System.Xml.XmlUrlResolver);
The right Powershell syntax to create boolean parameters seems to be $XsltSettings = New-Object System.Xml.Xsl.XsltSettings($true, $false);
I've done it this way : $XsltSettings = New-Object System.Xml.Xsl.XsltSettings $XsltSettings.EnableDocumentFunction = 1
3

This is working for me. The extra lines are for enabling scripts in the xsl.

EDIT. Seems the solution to above was that a line to enable the document function was needed. Similar to how I enable scripts.

$xslt_settings.EnableDocumentFunction = 1;

could be added to my function

function TransformXML{
    param ($xml, $xsl, $output)

    if (-not $xml -or -not $xsl -or -not $output)
    {
        Write-Host "& .\xslt.ps1 [-xml] xml-input [-xsl] xsl-input [-output] transform-output"
        return 0;
    }

    Try
    {
        $xslt_settings = New-Object System.Xml.Xsl.XsltSettings;
        $XmlUrlResolver = New-Object System.Xml.XmlUrlResolver;
        $xslt_settings.EnableScript = 1;

        $xslt = New-Object System.Xml.Xsl.XslCompiledTransform;
        $xslt.Load($xsl,$xslt_settings,$XmlUrlResolver);
        $xslt.Transform($xml, $output);

    }

    Catch
    {
        $ErrorMessage = $_.Exception.Message
        $FailedItem = $_.Exception.ItemName
        Write-Host  'Error'$ErrorMessage':'$FailedItem':' $_.Exception;
        return 0
    }
    return 1

}

3 Comments

This solution worked great for me. One small correction is the initial return 0 statement has a typoe.
Thanks, fixed the typo (finally)
after re-reading and this time understanding the comments to the accepted answer the original poster needed $xslt_settings.EnableDocumentFunction = 1; While my problem was that I was using a vbs script in the xsl and needed $xslt_settings.EnableScript = 1; Generally the problem in both cases was lack of understanding of the XsltSettings object.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.