Archiv für September, 2013

Ein universelles XSL-Stylesheet zum Aufteilen von XML-Dokumenten

Manchmal müssen große XML-Dokumente in kleinere Portionen zerlegt werden. In der Beispielsammlung gibt es dafür ein generisches Stylesheet (xml-aufteilen.xsl). Es teilt XML-Dateien auf der zweiten Ebene (unterhalb des Wurzelementes) in gleich große Gruppen mit bspw. 20 Elementen, umschließt diese Gruppen jeweils mit dem rekonstruierten Wurzelelement und ggfs. führenden Kommentaren und Processing Instructions und gibt die Gruppen als Einzeldateien aus.

Die Implementierung ist pures XSLT 2.0 auf der Grundlage von xsl:for-each-group group-adjacent="…" und xsl:result-document ohne Besonderheiten, deshalb gehe ich hier nicht näher auf den Code ein. Mit dem Stylesheet wird die zu teilende Eingabedatei transformiert, es entstehen eine Protokolldatei sowie die geteilten Dateien. Zahlreiche Parameter erlauben die Steuerung:

Auswahl der auszugebenden Elemente

elemente-pro-datei
(xs:integer) Anzahl der Elemente pro Ausgabedatei. Dieser Wert bestimmt die Größe der Gruppen und damit auch, welche Elemente als Gruppenanfang in Frage kommen. Ist bspw. $elemente-pro-datei gleich 20, dann sind mögliche Gruppenanfänge die Elemente mit der Position 1, 21, 41 usw. Damit wird sichergestellt, dass die Ausgabedateien (mit Ausnahme der letzten) immer vollständige Gruppen enthalten.
Mit einem Wert von 1 wird je Element eine Datei ausgegeben.
erstes-element
(xs:integer) Position des ersten zu kopierenden Elementes. Ohne Angabe eines Wertes wird das erste Element der zweiten Ebene gewählt. Fällt die angegebene Position nicht auf den Anfang einer Gruppe, der sich aus dem Wert für $elemente-pro-datei ergibt, wird das nächste vorhergehende Element, das ein Gruppenanfang ist, gewählt.
letztes-element
(xs:integer) Position des letzten zu kopierenden Elementes. Ohne Angabe eines Wertes wird das letzte Element der zweiten Ebene gewählt. Fällt die angegebene Position nicht auf das Ende einer Gruppe, der sich aus dem Wert für $elemente-pro-datei ergibt, wird das nächst folgende Element, das ein Gruppenende ist, gewählt.

Pfad und Name der Ausgabe-Dateien

Der vollständige Pfad zu den Ausgabedateien setzt sich aus einem für alle Dateien gleichem Pfad zum Ausgabeordner, einem Dateinamen-Präfix, den Zählstellen sowie der Dateityp-Erweiterung zusammen. Aus einer Eingabedatei mit Namen »daten.xml« entstehen bspw. »daten_001.xml«, »daten_002.xml« usw. (bei $elemente-pro-datei = 1) bzw. »daten_001-020.xml«, »daten_021-040.xml« usw. (bei $elemente-pro-datei = 20).

ausgabeordner
(xs:string) Ordner für die Ausgabe der geteilten Dateien als URI, ohne schließenden Schrägstrich. Ohne Angabe eines Ausgabeordners werden die Dateien in den Ordner des Ausgangsdokumentes in einen Unterordner »geteilt« geschrieben.
ausgabedatei-präfix
(xs:string) Präfix für die Ausgabedateien. Ohne Angabe eines Wertes wird der Name der Ausgangsdatei (ohne Dateierweiterung) mit einem nachgestellten Unterstrich verwendet.
ausgabedatei-erweiterung
(xs:string) Dateityp-Erweiterung für die Ausgabedateien. Ohne Angabe eines Wertes wird die Dateierweiterung der Ausgangsdatei verwendet.
picture-string
(xs:string) Formatierung der Zählstellen, als Picture-String (siehe https://wiki.selfhtml.org/wiki/XML/XSL/XPath/Funktionen#format-number.28.29_.28Zahl_in_Zeichenkette_umwandeln.29). Wird kein Wert übergeben, werden führende Nullen entsprechend der Anzahl der Elemente im Ausgangsdokument ausgegeben.

Extras

wiederhole-initiale-nodes
(xs:boolean) Steht dieser Parameter auf true, werden nodes() vor dem ersten Element (Kommentare und/oder Processing-Instructions) in jede Ausgabe-Datei an den Anfang kopiert. Bei false werden entsprechende Knoten nur in die erste Datei kopiert.
Vor dem Wurzelelement stehen oft Lizenzangaben in Kommentaren oder Processing Instructions wie bspw. das xml-model (siehe die W3C Working Group Note Associating Schemas with XML documents). Es kann wünschenswert sein, diese Informationen zu wiederholen.
schuetze-vorhandene-dateien
(xs:boolean) Verhindert, dass vorhandene Dateien überschrieben werden.
Um die Existenz einer Datei zu prüfen, muss die Datei geparst werden. Bei vielen und/oder großen bereits vorhandenen Ausgabedokumenten kann das sehr zeitaufwändig sein. In diesen Fällen empfiehlt es sich, erhaltenswerte Dokumente zu sichern und den Parameter auf false zu setzen.

Um das Stylesheet einfach an eigene Anforderungen anpassen zu können, wurden wichtige Subroutinen als Funktionen und benannte Templates angelegt. Diese können leicht überschrieben werden, um z.B. die auszugebenden Nodes zu filtern (Funktion local:nodes-auswaehlen() oder um ein eigenes Benennungsschema (Funktion local:dateiname()) zu realisieren.

Keine Kommentare