- 1 Intro
- 2 Anwendungsgebiete
- 2.1 XSLT - die Programmiersprache im XML Bereich
- 2.2 Aktuelle und vergangene Anwendungen
- 2.3 Professionelle XML Verarbeitung
- 2.4 Technische Dokumentation
- 3 Wichtige Konzepte
- 3.1 Push vs. Pull Stylesheets
- 3.2 Eindeutigkeit der Regelbasis
- 3.3 Namespaces
- 3.4 Schemata
- 3.5 Standards
- 3.5.1 DITA
- 3.5.2 DITA Inhaltsmodell
- 3.5.1 DITA
- 4 Ausgewählte Themen
- 4.1 Transformationen mit XSLT
- 4.1.1 Vortransformationen
- 4.1.2 Komplexe XML-2-XML Transformationen
- 4.1.2.8 Vererbung
- 4.1.2.8 Vererbung
- 4.1.3 XSLT Streaming
- 4.1.3.1 XSLT Akkumulator
- 4.1.3.2 XSLT Iterator
- 4.1.4 Reguläre Ausdrücke
- 4.1.5 Modus vs. Tunnel Lösung
- 4.1.6 Identifikation mit
generate-id()
- 4.1.6.4 XPath-Achsenbereich selektieren
- 4.1.6.4.1 Funktionen und Module
- 4.1.6.4.1 Funktionen und Module
- 4.1.6.4 XPath-Achsenbereich selektieren
- 4.1.7 Webservice Calls mit doc() und unparsed-text()
- 4.1.8 Stylesheet-Parameter auf der Kommandozeile
- 4.1.9 Leerzeichenbehandlung
- 4.1.10 Mit
translate
Zeichen ersetzen
- 4.1.10.1 Spass mit dem Sequenzvergleich
- 4.1.11 Character Mappings in der Ausgabe
- 4.1.12 JSON mit XSLT 1.0 und Python lxml
- 4.1.1 Vortransformationen
- 4.2 Abfragen mit XQuery
- 4.2.5 XQuery als Programmiersprache
- 4.2.5.3
if..then..else
Ausdrücke
- 4.2.5.3.2 SQL Views in MarkLogic
- 4.2.5.3
if..then..else
Ausdrücke
- 4.2.6 Hilfreiche XQuery Schippsel
- 4.2.5 XQuery als Programmiersprache
- 4.3 XML Datenbanken
- 4.3.1 Connector zu Marklogic in Oxygen
- 4.3.2 Bi-Temporale Dokumente
- 4.3.2.1 Anlegen des Testszenarios auf der ML Konsole
- 4.3.2.2 Ausführen einiger Beispiel-Queries
- 4.3.3 Webapps mit MarkLogic
- 4.3.3.5 Wikipedia Scrapper Applikation
- 4.3.3.5 Wikipedia Scrapper Applikation
- 4.3.4 Dokument-Rechte in MarkLogic
- 4.3.5 MarkLogic Tools
- 4.3.5.1 EXPath Konsole
- 4.3.5.2 mlcp - MarkLogic Content Pump
- 4.3.5.3 Deployment-Tools
- 4.4 XSL-FO mit XSLT1.x
- 4.5 Testing
- 4.5.1 Validierung mit Schematron
- 4.5.2 Erste Schritte mit XSpec
- 4.5.1 Validierung mit Schematron
- 4.6 Performanz-Optimierung
- 4.1 Transformationen mit XSLT
- 5 Zusätzliches Know-How
- 5.1 XML Editoren
- 5.2 Quellcode-Versionskontrolle
- 5.2.1 Kurze Geschichte zur Versionskontrolle Test
- 5.2.2 GIT Kommandos
- 5.2.1 Kurze Geschichte zur Versionskontrolle Test
- 5.1 XML Editoren
- 6 Glossary
- 7 Tektur CCMS
4.1.5 Modus vs. Tunnel Lösung
Als Entwickler wird man oft mit der Situation konfrontiert, dass es zur Lösung eines bestimmten Problems mehrere
Möglichkeiten gibt und man eine davon auswählen muss.
Hier gilt es einen Trade-Off aus teils konkurrierenden Zielen zu finden, wie das folgende Beispiel zeigt. Betrachten wir ein Konto:
<konto nr="123"> <inhaber>alex</inhaber> <vorgang>456</vorgang> <eintrag art="soll" datum="2019-05-06">20.56</eintrag> <eintrag art="soll" datum="2019-02-21">4.73</eintrag> <eintrag art="haben" datum="2019-01-14">1.68</eintrag> <eintrag art="soll" datum="2019-09-17">6.45</eintrag> <eintrag art="haben" datum="2019-01-03">12.38</eintrag> [...] </konto>
Es gibt nun mehrere Möglichkeiten die Bilanz in zwei Dateien
soll.xml
und
haben.xml
aufzusplitten.
4.1.5.1 Schleife
<xsl:template match="/"> <xsl:result-document href="soll.xml"> <konto nr="{@nr}"> <inhaber><xsl:value-of select="inhaber"/></inhaber> <vorgang><xsl:value-of select="vorgang"/></vorgang> <xsl:for-each select="konto/eintrag"> <xsl:if test="@art='soll'"> <xsl:copy-of select="."/> </xsl:if> </xsl:for-each> </konto> </xsl:result-document> <xsl:result-document href="haben.xml"> [...] </xsl:template>
Hier werden die gemeinsamen Felder für das Konto
<inhaber>
und
<vorgang>
hartcodiert,
was in dem einfachen Beispiel okay wäre. Aber eigentlich wollen wir ja Pull-Stylesheets vermeiden, vgl.
Push vs. Pull Stylesheets.
4.1.5.2 Tunnel Parameter
<xsl:template match="/"> <xsl:result-document href="soll.xml"> <xsl:apply-templates> <xsl:with-param name="is-soll" select="true()" tunnel="yes"/> </xsl:apply-templates> </xsl:result-document> <xsl:result-document href="haben.xml"> <xsl:apply-templates> <xsl:with-param name="is-soll" select="false()" tunnel="yes"/> </xsl:apply-templates> </xsl:result-document> </xsl:template> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match="eintrag"> <xsl:param name="is-soll" tunnel="yes"/> <xsl:choose> <xsl:when test="$is-soll and @art='soll'"> <xsl:copy-of select="."/> </xsl:when> <xsl:when test="not($is-soll) and @art='haben'"> <xsl:copy-of select="."/> </xsl:when> <xsl:otherwise/> </xsl:choose> </xsl:template>
Hier werden über eine Default-Kopierregel alle Knoten des XML Gerüsts kopiert, d.h. das Gerüst kann
beliebig gross sein, und wir brauchen uns darum nicht kümmern. Insofern ist diese Lösung einen
Schritt weit generischer, als die zuvor gezeigte.
Wir sind sogar sehr flexibel was Änderungen angeht, da im Eintrag-Template leicht weitere Logik
implementiert werden kann, die über alle Zweige der bedingten Anweisung greift, bspw. mittels
einer lokalen Variablen, die einen Berechnungsausdruck enthält.
4.1.5.3 Mode Attribut
(Noch) kürzer geht es dagegen mit dem
mode
Attribut:
<xsl:template match="/"> <xsl:result-document href="soll.xml"> <xsl:apply-templates mode="soll"/> </xsl:result-document> <xsl:result-document href="haben.xml"> <xsl:apply-templates mode="haben"/> </xsl:result-document> </xsl:template> <xsl:template match="node()|@*" mode="#all"> <xsl:copy> <xsl:apply-templates select="node()|@*" mode="#current"/> </xsl:copy> </xsl:template> <xsl:template match="eintrag[@art='soll']" mode="haben"/> <xsl:template match="eintrag[@art='haben']" mode="soll"/>
Der Trick ist hier, dass im jeweils anderen Modus, gerade die
ausgewählten Knoten nicht kopiert werden, was schliesslich die
Eingabe korrekt in Soll und Haben aufteilt. Wenn wir weitere Logik
hinzufügen wollen, müssten wir die Templates ein bisschen umbauen, was nicht weiter
tragisch sein sollte.
Der Trade-Off besteht also aus den meist konkurrierenden Zielen Redundanz einzusparen,
d.h. den Quelltext so kurz und knapp wie möglich zu gestalten, und
einer zukünftigen leichten Erweiterbarkeit.