Automatisierung von XSL-Transformationen mit SSIS und Powershell bzw. MSXSL

Authors: Thorsten Huss

Im Rahmen der Planung zum Einsatz eines Testwerkzeugs stellte sich uns in den letzten Tagen die Frage, wie XML-Dateien mit Testergebnissen möglichst automatisch auf Grundlage einer vorhandenen XSL-Datei zu anschaulicheren HTM-Dateien zu parsen sind. Da die Automatisierung möglichst über die bekannte Arbeitsumgebung ablaufen sollte, waren die Voraussetzungen daher zum einen, möglichst wenige Zusatzwerkzeuge installieren zu müssen, zum anderen nach Möglichkeit ein ETL-Paket zur Ausführung zu nutzen. Eine kurze Recherche grenzte die Wahl des Parse-Werkzeugs schnell auf die MSXSL.exe von Microsoft sowie ein Powershell-Skript ein. Andere Werkzeuge wie Saxon oder Oxygen erfüllten die Voraussetzungen nicht zu unserer Zufriedenheit.

Der MSXSL-Weg

Zunächst einmal muss von http://www.microsoft.com/en-us/download/details.aspx?id=21714 die MSXSL.exe heruntergeladen werden. 25KB sollten keine Leitung oder Festplatte überlasten.

In der Kommandoeingabe muss folgender Befehl verwendet werden, um die MSXSL.exe aufzurufen und mit einer gegebenen XML- und XSL-Datei die Transformation durchzuführen (jeweils die richtigen Dateipfade angeben!):

<msxsl.exe> -o < Outputdatei.htm> < XML-Datei> < XSL-Datei>

Das ist beim reinen MSXSL-Weg auch schon alles!

Der Powershell-Weg

Die Powershell sollte im Normalfall bereits installiert sein. Bevor man anfangen kann, sind jedoch zwei Dinge zu beachten: Es muss die 32-Bit-Version verwendet werden. Außerdem muss sie einmalig als Administrator ausgeführt werden um den Befehl Set-ExecutionPolicy RemoteSigned anzuwenden. Andernfalls kann kein eigenes Skript ausgeführt werden. Dieses wird jedoch benötigt und sieht wie folgt aus:

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”

                exit;

}

trap [Exception]

{

                Write-Host $_.Exception;

}

$xslt = New-Object System.Xml.Xsl.XslCompiledTransform;

$xslt.Load($xsl);

$xslt.Transform($xml, $output);

Write-Host “generated” $output;

Wichtig: vor dem param()-Befehl dürfen nur Kommentare oder Whitespaces stehen! Die Parameter können mit einem direkt angeführten „= Wert“ gefüllt werden. Da sie später jedoch die Werte aus dem ETL-Prozess erhalten sollen, ist dies hier nicht notwendig. Nach Belegung der Parameter wird überprüft, ob alle vorhanden sind und keine Exception vorliegt, anschließend wird in drei Schritten der Transformationsprozess abgeschlossen. Dieses Skript ist mit der Dateiendung .ps1 abzuspeichern. Der Aufruf erfolgt schließlich in der Powershell mit diesem Befehl:

<.ps1-Datei> <XML-Datei> <XSL-Datei> <Output-Datei>

Wiederum ist auf die richtigen Dateipfade zu achten. Etwas schwieriger als MSXSL, aber das war es!

Automatisierung mit ETL-Paket in SQL Server Integration Services

Der Prozess wird in beiden Varianten mit denselben Schritten via ETL automatisierbar.

In einem frischen Integration-Services-Projekt wird ein Foreach Loop Container in den Kontrollfluss gezogen, welcher einen Execute Process Task beinhaltet.

 Automatisierung von XSL-Transformationen mit SSIS und Powershell bzw. MSXSL

Mit markiertem Container werden vier Variablen als String angelegt:

Output, XML und XSL für die jeweiligen Dateipfade, MSXSL bzw. Skript für den Pfad zur MSXSL.exe bzw. zum .ps1-Skript. Als Default-Wert kann optional ein Standardpfad angegeben werden.

Um der Output-Datei denselben Namen wie der Input-Datei zu geben und die Dateiendung auf .htm zu ändern, muss die Variable markiert und unter den Einstellungen per Klick auf (…) bei Expression der Expression-Editor geöffnet werden. Hier wird der Wert SUBSTRING( @[User::XML] , 1,  LEN( @[User::XML]  ) – 4) + “.htm” eingegeben. Anschließend noch den Wert für EvaluateAsExpression auf True setzen.

Im Container-Editor wird unter Collection -> Folder auf den Ordner mit den Testergebnisdateien verwiesen, unter Files werden alle Dateien mit dem Schema *.xml durchsucht. Unter Variable Mappings wird die eben angelegt Variable XML zugewiesen.

Im Execute Process Task wird unter Process -> Executable der Dateipfad der Kommandoeingabe (cmd.exe, meistens unter C:\Windows\System32) bzw. der 32-Bit-Powershell.exe angegeben. Unter Expressions -> Expressions wird per Klick auf (…) der Expression-Editor geöffnet. Links wird der Wert Arguments ausgewählt. Nun werden entsprechend der oben geschilderten Befehle die Variablen als Argument deklariert.

MSXSL:“/C ” + @[User::MSXSLPath] + ” -o ” + @[User::Output] + ” ” + @[User::XML] + ” ” +  @[User::XSL]

Powershell:@[User::Script] + ” ” + @[User::XML] + ” ” +  @[User::XSL] + ” ” +  @[User::Output]

Führt man jetzt das Paket aus, wird für jede gefundene XML-Datei eine Transformation durchgeführt und eine entsprechende HTM-Datei erstellt.