- 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.2.8 Vererbung
Mit XSLT kann man Konstrukte aus anderen Programmierparadigmen nachbilden, bspw. Vererbung. Dabei wird in einer Spezialisierung eine schon bereits getätigte Implementierung übernommen und erweitert oder eingeschränkt.
Der Vorteil dabei ist, dass man nicht alles nochmal neu schreiben muss. Das verkleinert die Redundanz, führt zu einer besseren Wartbarkeit und einer geringeren Fehleranfälligkeit.
4.1.2.8.1 Beispiel: Parameterisierung
Gewöhnlich implementiert man ein Stylesheet für ein bestimmtes Ausgabeformat und eine Produktvariante. Schrittweise werden dann weitere Varianten und Formate hinzugefügt.
Am komfortabelsten hat man es natürlich, wenn zu Beginn der Implementierung eine vollständige Spezifikation vorliegt... Das ist aber natürlich eher selten der Fall.
Aus diesem Grund ist es wichtig, sich eine gute Strategie zu überlegen, damit die Architektur nicht in Spaghetthi-Code ausartet.
Eine gute Option wäre, die XSLT Import Präzedenz auszunutzen, vgl. Kapitel Eindeutigkeit der Regelbasis .
Will man zu einem späteren Zeitpunkt weitere Parameter einzuführen, dann müsste ein Switch, wie der folgende, an mehreren Stellen im Code aktualisiert werden.
<xsl:choose> <xsl:when test="$myParameter='this_option'"> <!-- do this --> </xsl:when> <xsl:when test="$myParameter='that_option'"> <!-- do that --> </xsl:when> [...] </xsl:choose>
Besser ist es, wenn man ein Core-Stylesheet pflegt, das für ein Format und eine Produktvariante gut ausgetestet ist. Dieses Core-Stylesheet wird dann einfach für eine neue Variante importiert und relevante Teile werden für die neue "Spezialisierung" überschrieben. Beispielsweise könnte eine Regel zum Setzen des Headers auf jeder Seite so implementiert sein:
<xsl:template name="render-header"> <!-- print logo on the left side spanning two rows--> <!-- print some metadata right side first row --> <!-- print a running header right side second row --> </xsl:template>
Wird in einem neuen Format, bspw. A5, diese Logik ausgetauscht und nur eine Zeile gedruckt, z.B. weil man nicht so viel Platz hat, so würde in einem "abgeleiteten" Stylesheet einfach die Regel noch einmal implementiert.
<xsl:choose> <xsl:template name="render-header"> <!-- print a running header on left side --> <!-- print logo on right side --> </xsl:template>
Dieses Template hat nun Vorrang und wird zur Auswertung herangezogen, mit der Konsequenz, dass der Header nur einzeilig gedruckt wird. Das schöne an diesen "Named-Templates" ist auch, dass man sie innerhalb von Variablen verwenden kann:
<xsl:variable name="margin-width"> <xsl:call-template name="get-margin-width"/> </xsl:variable>
Das Template
get-margin-width
kann in einem "Sub"-Stylesheet überschrieben werden, ohne dass die Variablen-Zugriffe im Core-Stylesheet angepasst werden müssen. Eine Zuweisung, wie:
width="{$margin-width}"
müsste nirgendwo im Code nochmal angefasst werden, was natürlich sehr komfortabel ist.
4.1.2.8.2 Beispiel: Spezialisierte Fallunterscheidung
Kommt ein Ausgabeformat zu einem späteren Zeitpunkt hinzu, so kann man die Vererbung nutzen um clever zwischen den Ausgabeformaten zu unterscheiden. Ein bestehendes Template
"cover"
:
<xsl:template match="cover"> <fo:page-sequence master-reference="coverFront" force-page-count="auto"> <fo:flow flow-name="xsl-region-body"> [...] <fo:page-sequence master-reference="coverBack" force-page-count="auto"> <fo:flow flow-name="xsl-region-body"> [...]
kann aufgesplittet werden in ein Template für eine Vor- und Rückseite:
<xsl:template match="cover"> <fo:page-sequence master-reference="coverFront" force-page-count="auto"> <fo:flow flow-name="xsl-region-body"> [...] </xsl:template> <xsl:template name="cover-back-switch"> <xsl:call-template name="cover-back"/> </xsl:template> <xsl:template name="cover-back"> <fo:page-sequence master-reference="coverBack" force-page-count="auto"> <fo:flow flow-name="xsl-region-body"> [...]
Das Template
"cover-back-switch"
kann dann in einem Ausgabeformat überschrieben werden, um bspw. die Cover-Rückseite abhängig von einer Bedingung zu schalten.
Einen Algorithmus in einer Superklasse grob zu strukturieren und Details in Unterklassen zu verfeinern, ist ein gängiges Design Pattern in der Objektorientierten Programmierung. Diese Methodik kann auch sehr schön mittels Named-Templates in XSLT realisiert werden. Nicht umsonst heisst das OO Pattern dazu Template Method ↗