4.1.3.1 XSLT Akkumulator
Ein einfaches Streaming Stylesheet könnte z.B. so aussehen:
<xsl:stylesheet version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all">
<xsl:output method="xml" indent="yes"/>
<xsl:mode on-no-match="shallow-copy" use-accumulators="entry-count" streamable="true"/>
<xsl:accumulator name="entry-count" as="xs:integer" initial-value="0"
streamable="yes">
<xsl:accumulator-rule match="entry" select="$value + 1"/>
</xsl:accumulator>
<xsl:template match="/">
<result>
<xsl:apply-templates/>
<count>
<xsl:value-of select="accumulator-after('entry-count')"/>
</count>
</result>
</xsl:template>
</xsl:stylesheet>
Diese Stylesheet hat einige Besonderheiten:
(Auf herkömmlichem Weg würde man dafür ein Templates, wie dieses, verwenden:)
<xsl:template match="node()|@*"
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
Zum anderen wird ein Akkumulator verwendet. Normalerweise gibt es in XSLT keine Variablen,
sondern nur Konstanten, wie das auch bei funktionalen Programmiersprachen der Fall ist.
Es gab zwar schon länger eine Saxon-Erweiterung, die die mehrmalige Zuweisung eines Wertes
an eine Variable erlaubte, im Normallfall braucht man diese Eigenschaft aber nicht.fred
Ber der Verarbeitung sehr großer Datemengen, sind aber zuweisbare Variablen unumgänglich, denn sonst
würde der Laufzeitstapel schnell an seine Grenzen gelangen.
Ein Akkumulator akkumuliert Werte, wie der Name schon sagt. Das können atomare Typen sein,
wie im obigen Beispiel, aber auch Datenstrukturen können aufgebaut werden, wie
bspw. der gerade prozessierte Teilbaums in einem Dictionary. (Um spätere eine Auswertung bzw. Gruppierung der Key-Elemente
durchführen zu können).
Im Akkumulator muss das
streamable="yes"
Property gesetzt sein, wenn er im
Streaming-Modus arbeiten soll. In diesem Modus kann der Akkumulatorwert erst ausgelesen werden,
wenn der untersuchte Baum vollständig durchlaufen wurde.
Um die Unterschiede zum "normalen" XSLT Betrieb festzustellen, können im obigen Beispiel
einige offensichtlich korrekte Änderungen vorgenommen werden, die der Streaming
Prozessor allerdings nicht akzeptiert.
Cannot call accumulator-after except during the post-descent
phase of a streaming template
Diese Fehlermeldung erscheint, wenn man den
apply-templates
Call entfernt. Der Akkumulator
wird also nur befüllt, wenn der Baum auch explizit durchlaufen wurde. Dieser Durchlauf
kann auch ein reines Kopieren sein, bspw. kann man den
apply-templates
Call auch durch ein
<xsl:copy-of select="."/>
ersetzen, was gleichbedeutend mit der Mode Einstellung
wäre. Wie man sieht hat sich in XSLT 3.0 viel bzgl. der Handhabung verschiedener
Verarbeitungsmodi getan. Anstatt Default-Match Regeln zu schreiben, setzt man in der Stylesheet Deklaration bestimmte Modus
Properties, die den Baumdurchlauf auf verschiedene
Arten realisieren.
Die Verarbeitung großer Datenmengen ist aber mit Streaming etwas tricky!
Es sollte geprüft werden, ob ggf. konventionelles Performanz-optimiertes XSLT für den Answendungsfall ausreicht.