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.)

  1. 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.

  2. 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.

  3. 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)

  4. 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] oder exists(parent::paper).

    Nicht erlaubt ist: parent::paper[name = 'John Doe'] (im Prädikat steckt ein Abwärtsausdruck) oder parent::paper/string() (Geschwister-Elemente müssten eingelesen werden).

  5. Burst-Mode.

    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.

  6. 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] oder price[@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: