Streamability-Regeln
Es werden zunächst geläufige Begriffe aus dem Bereich von XSLT-Streaming erläutert. Im Anschluss daran erfolgt eine Auflistung einiger zu beachtender Regeln. Diese Regeln müssen eingehalten werden, um Dateien im Streaming-Modus verarbeiten zu können.
Begriffe
Die folgenden Erklärungen der Begriffe aus dem Umfeld von XSLT-Streaming stammen von Michael Kay, Streaming in the Saxon XSLT Processor. in: XML Prague 2014 Conference Prodeedings. Februar 2014. XML Prague 2014. S. 83f.
Sweep
sweep = abtasten; beschreibt wie häufig das Input-XML-Dokument benötigt wird, um das jeweilige Konstrukt auszuwerten.
motionless = bewegungslos
Ausdrücke sind bewegungslos, wenn der XSLT-Prozessor sich zur Verarbeitung nicht von der aktuellen Position im XML-Stream entfernen muss bzw. nur den aktuellen Kontext verwendet. Alternativ ist ein Ausdruck auch bewegungslos, wenn das Input-Dokument nicht verwendet wird.
Zum Beispiel
name()
oder Attribute des aktuellen Knotens.consuming = verbrauchend
Das Konstrukt muss zur Verarbeitung den gesamten Inhalt zwischen Start- und Ende-Tag des aktuellen Elements lesen.
Beispiele:
string()
,data()
,number()
,xsl:value-of
,xsl:copy
.free-ranging = kontextunabhängig
Das Konstrukt benötigt Daten vom gestreamten XML-Dokument außerhalb des aktuellen Kontexts. Vom Kontext sind nur das aktuelle Element, die zugehörigen Attribute und alle Vorfahren-Elemente inklusive deren Attribute erreichbar.
Beispiele:
preceding-sibling::abc
,following-sibling::abc
,xsl:number
.Die Folge ist, dass kein Streaming möglich ist, da Elemente außerhalb, wie Geschwister-Elemente oder vorhergenende bzw. nachfolgende Elemente, des Kontexts benötigt werden.
Posture
posture = Lage; beschreibt woher ein Element bzw. ein Knoten des Input-XML-Dokuments kommt, welches von einem Ausdruck verarbeitet wird.
grounded = fixiert
Der Ausdruck gibt keine Elemente vom gestreamten Input-Dokument zurück. Es werden entweder atomare Werte oder Elemente von einem nicht gestreamten Dokument zurückgegeben.
striding = schreiten
Der Ausdruck gibt Elemente vom gestreamten Input-Dokument zurück. Aber keines der zurückgelieferten Elemente enthält weitere Elemente.
crawling = kriechen
Der Ausdruck gibt Elemente vom gestreamten Input-Dokument zurück. Allerdings können diese im Gegensatz zu striding Kind-Elemente enthalten.
climbing = klettern
Alle Vorfahren-Elemente und Attribute sind vom aktuellen Kontext aus verfügbar. Die Einschränkung ist allerdings, dass man anschließend keinen Zugriff auf das aktuell verarbeitete Element mehr hat.
roaming = schlendern
Ein Ausdruck navigiert zu Teilen des Dokuments, welche beim Streaming nicht verfügbar sind. Dies können Geschwister-Elemente oder vorhergehende bzw. nachfolgende Elemente sein.
Regeln
Zu den Streamability-Regeln lässt sich sagen, dass der Prozessor ein Dokument in einem einzigen Durchlauf verarbeitet und somit jeder Knoten nur einmal besucht wird. Eine mehrfache Verarbeitung von Elementen ist nicht vorgesehen. Dies führt dazu, dass Stylesheets, welche nicht zum Streamen geschrieben wurden, meistens umgeschrieben werden müssen.
Beim Streaming sind nur der aktuelle Knoten, die Vorfahren (inklusive Attribute) und die Nachfahren (inklusive Attribute) verfügbar. Geschwister-Elemente, vorherige und nachfolgende Elemente sind nicht verfügbar. (Vgl. o. V. XSL Transformations (XSLT) Version 3.0: 2.10 Streaming.)
Faustregeln zur Streamability
(Vgl. Abel Braaksma. XSLT 3.0 Streaming for the masses. in: XML Prague 2014 Conference Prodeedings. Februar 2014. XML Prague 2014. S. 40-59.)
Jedes Template darf maximal einen Abwärts-Ausdruck enthalten.
Zum Beispiel <xsl:apply-templates select="Ausdruck"/>,
<xsl:value-of select="Ausdruck"/>
etc.Hilfreich ist es, die Verarbeitung der Kind-Elemente auf mehrere Templates aufzuteilen, um die Einschränkungen dieser Regel zu umgehen.
Jedes Konstrukt darf maximal einen Abwärts-Ausdruck enthalten.
Ein Konstrukt ist eine Anweisung, ein Ausdruck, z. B.
xsl:template
,xsl:for-each
,xsl:iterate
,xsl:apply-templates
,xsl:sequence
etc.Falls möglich, bewegungslose Ausdrücke verwenden.
Beispiele:
name()
,self::abc
oder@abc
(Attribut-Achse)XPath-Funktionen, welche nur atomare Werte als Parameter verwenden (
string(.)
)XPath-Funktionen, welche keinen Eingabewert aus dem XML-Stream verwenden (
current-dateTime()
)XPath-Funktionen, welche nur mit dem aktuellen Knoten arbeiten (
exists(.)
,not(.)
)Anweisungen zum Erstellen von neuen Knoten (
xsl:comment
,xsl:element
,xsl:attribute
)
Man kann sich den Baum hoch bewegen, aber nicht mehr zurück.
Dies ist möglich, da die Vorfahren-Achse im Arbeitsspeicher gehalten wird. Es wird davon ausgegangen, dass eine XML-Datei eine beschränkte Hierarchie hat und alle benötigten Informationen der Vorfahren-Elemente somit im Arbeitsspeicher gehalten werden können.
Geht man den Baum hoch, besteht kein Zugriff mehr auf den aktuellen Knoten, da sonst alle Geschwister-Elemente im Arbeitsspeicher gespeichert sein müssten. Ein Beispiel wäre das Auslesen eines Attributs eines Vorfahren-Elementes.
Erlaubt ist:
parent::paper[parent::archive]
oderexists(parent::paper)
.Nicht erlaubt ist:
parent::paper[name = 'John Doe']
(im Prädikat steckt ein Abwärtsausdruck) oderparent::paper/string()
(Geschwister-Elemente müssten eingelesen werden).Um die Einschränkungen des XSLT-Streamings (zumindest teilweise) zu umgehen, ist es möglich, Sub-Trees in einem zusätzlichen Nicht-Streaming-Modus zu verarbeiten. In diesem Modus gibt es keine Einschränkungen und es stehen alle Möglichkeiten der XSLT-Verarbeitung zur Verfügung.
Diese Methode wird häufig "Burst-Mode" oder "Windowed Streaming" genannt.
Zur Verarbeitung wird der gesamte Sub-Tree in einer Variable gespeichert und dieser in einem extra Modus, ohne Streaming, verarbeitet.
Bei der Entwicklung muss darauf geachtet werden, dass der Sub-Tree in den Arbeitsspeicher passt. Häufig ist dies aber kein Problem, da kleine Teilstücke oft unabhängig voneinander verarbeitet werden können (einzelne Adresse eines Adressverzeichnisses, ein Buch einer Büchersammlung etc.).
Beispiele zum Einsatz des Burst-Modes siehe Burst-Mode.
Bewegungslose Filter verwenden.
Für Prädikate in XPath-Ausdrücken gelten die gleichen Regeln wie für bewegungslose Ausdrücke. Beispiele für bewegungslose Filter:
*[self::para]
oderprice[@currency[starts-with(.,'EUR')]]
.
<< zurück | vor >> |
Tipp der data2type-Redaktion: Zum Thema XSLT bieten wir auch folgende Schulungen zur Vertiefung und professionellen Fortbildung an: |