Your browser doesn't support the features required by impress.mod.js, so you are presented with a simplified version of this presentation.

For the best experience please use the latest Chrome, Safari or Firefox browser.

2021 | Mainz

Einführung in X-Technologien


Modellieren, Strukturieren, Repräsentieren

Sektion 4: XSLT

Slides: Link

Max Grüntgens | Dominik Kasper | @digicademy | Twitter digicademy | CC-BY 4.0

Table of Contents

  1. XSLT allgemein
    1. Erklärung
    2. Use Cases
  2. Grundprinzipien
    1. Das XSLT Stylesheet
      1. Stylesheet-Element
      2. Template-Element
    2. Pull-Verarbeitung
      1. Einfache Pull-Verarbeitung mit value-of
      2. Komplexe Pull-Verarbeitung mit Schleifen
    3. Push-Verarbeitung
      1. Rekursion
      2. Hidden Text Template und Identity Transform-Prinzip
  3. Spezifischere Funktionalitäten

01

XSLT allgemein

XSLT allgemein

Erklärung

XSLT - eXtensible Stylesheet Language Transformation

XSLT ist eine Transformationssprache für XML-Dokumente. Ein XSLT-Prozessor verarbeitet ein XML-Dokument gemäß der Angaben in einem XSLT-Dokument und erzeugt ein Ergebnisdokument (oder mehrere) in einem Format (z. B. Plain Text, XML, HTML), welches vom XSLT-Dokument bestimmt wird.

Institut für Dokumentologie und Editorik: XML - Kurzreferenz für Einsteiger (Hervorhebungen nicht im Original)

XSLT liegt inzwischen in der dritten Version (3.0) vor.

XSLT allgemein

Paradigma

XSLT ist eine deklarative Programmiersprache.

Weitere deklarative Sprachen sind bspw. SQL, SPARQL und Cypher. Die bekannteren deklarativen Sprachen dienen der Daten-Abfrage und -Akquise.

XSLT allgemein

Versionen

Hinweis: In den Libraries vieler Programmiersprachen wurde XSLT nur bis einschließlich Version 2.0 implementiert. Eine umfassende Implementierung von XSLT 3.0 existiert nur als Saxon-C für Java, C/C++, PHP und neuerdings auch für Python 3 (hierzu mehr hier und hier).

XSLT allgemein

Use Cases

Transformation von XML-Dokument(en) …

Extraktion von …

Hinweis: Extraktionen sind im Grunde Spezialfälle von Transformationen.

02

Grundprinzipien

Grundprinzipien

Das XSLT Stylesheet

Das XSL-Wurzelelement I

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0"></xsl:stylesheet>

Alternativ kann auch das Synonym <xsl:transform> verwendet werden. Die Gründe sind historischer Art.

Wichtig: Ein XSL-Dokument ist stets ein wohlgeformtes XML-Dokument!
Wichtig: Die Angabe des @xmlns:xsl-Namespaces ist obligatorisch!

Das XSLT Stylesheet

Das XSL-Wurzelelement II

Konfiguration über Attribute und Kind-Elemente
<xsl:stylesheet
    xpath-default-namespace="http://www.tei-c.org/ns/1.0" 1
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 2
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    exclude-result-prefixes="#all" 3
    version="3.0"> 4
        <xsl:output indent="yes" method="xml"/> 5
        <xsl:mode on-no-match="shallow-copy"/> 6
</xsl:stylesheet>

1 @xpath-default-namespace definiert den TEI-Namespace als standardmäßigen Namespace.
2 Alle weiteren relevanten Namespaces werden über das Präfix definiert, e.g. @xmlns:xsl
3 @exclude-result-prefixes schließt mittels #all alle Namespaces aus der Ergebnisdatei aus.
4 @version wird auf 3.0 gesetzt, um die neuesten Features zu nutzen.
5 output
… sorgt per @indent für automatisches Code-Formatieren der Ergebnisdatei.
… sorgt per @method dafür, dass xml als Ausgabe produziert wird.
6 mode
… sorgt mit @on-no-match und dem Wert shallow-copydafür, dass Knoten, für die im Push-Workflow kein passendes Template existiert, unverändert in den Ergebnisbaum kopiert werden.

Tipp: Das Beispiel oben ist ein guter Ausgangspunkt zur Transformation und Extraktion von TEI-XML in allgemeines XML.

Das XSLT Stylesheet

Das XSL-Template-Element

xsl:template-Elemente sind Kind-Elemente des xsl:stylesheet-Elements
<xsl:template match="/root" >
    /* Verarbeitet spezifische Knoten via XPath-navigation, e.g. */
    <xsl:value-of select="head/title" />.
    /* Der aktuelle Kontext-Knoten ist "/root". */
</xsl:template>

Grundprinzipien

Pull-Verarbeitung

Einfache Pullverarbeitung mit xsl:value-of

<xsl:template match="/TEI">
    <document>
        <meta>
            <title>
            <xsl:value-of 1 select="teiHeader/fileDesc/titleStmt/title"2/>
            </title>
        </meta>
        <persons>
            <p>Add the xsl for persons hear.</p>
        </persons>
    </document>
</xsl:template>
Übung: Bitte öffnen Sie die Dateien Uebungen/Sturm_persList.xml und Uebungen/base_xslt.xsl, kopieren Sie obigen Code an die korrekte Stelle in der Datei und ergänzen Sie den Header-Bereich in document/meta durch weitere Information aus dem TEI-Header der Quelldatei.

Grundprinzipien

Pull-Verarbeitung

Komplexe Pullverarbeitung mit xsl:for-each (Schleifen)

<xsl:template match="/TEI">
    <document>
        <meta>
            <p>Add the xsl for meta information aggregation here.</p>
        </meta>
        <persons>
            <xsl:for-each 1 select="text/body//listPerson/person"2>
                <name><xsl:value-of select="persName"/>3</name>
            </xsl:for-each>
        </persons>
    </document>
</xsl:template>
Übung: Bitte öffnen Sie die Dateien Uebungen/Sturm_persList.xml und Ressourcen/XSLT/Sturm_persList.xsl und ergänzen Sie den xsl:for-each-Bereich in document/persons durch weitere Information aus der Quelldatei.

Grundprinzipien

Push-Verarbeitung mit Rekursion

<xsl:template match="/TEI">
    <document> <meta> <p>Add the xsl for meta information aggregation here.</p> </meta>
        <persons>
            <xsl:for-each 1 select="text/body//listPerson/person"2>
                <xsl:apply-templates 4 select="."3/>
            </xsl:for-each>
        </persons>
    </document>
</xsl:template>
5<xsl:template 6 match="person" 7> 
    8<record type="person"><xsl:apply-templates 9/></record>
</xsl:template>
5<xsl:template match="persName"> 
    <name><xsl:apply-templates/></name>
</xsl:template>
5<xsl:template match="linkGrp" /> 
Übung: Bitte erläutern Sie, 1) warum die Tags person nicht in der Ausgabedatei auftauchen. 2) warum ptr-Tags nicht in der Ausgabedatei auftauchen.
Bitte schreiben Sie weitere Templates, um weitere Informationen in der Ausgabedatei auszugeben.

Grundprinzipien

Hidden Text Template und Identity Transform-Prinzip

XSLT 1.0 & 2.0 verfügen nicht über Konfigurationsmöglichkeiten, die es gestatten, festzulegen, wie mit Knoten umgegangen werden soll, für die kein “matchendes” Template existiert. In diesen Fällen greifen die sogenannten “hidden templates”. Diese führen dazu, dass es bei fehlendem Template-Match immer zu einem Minimal-Output an Text(-knoten) kommt. Alle sonstigen Knoten gehen bei diesem “Notfall-Match” verloren.

Hidden Text Template und Identity Transform-Prinzip

Will man in XSLT 1.0 & 2.0 sämtliche Knoten, für die kein Template definiert wurde, erhalten, muss ein sogenanntes “Identity Transform-Template” eingebunden werden, dessen Regel derart allgemein ist, dass alle Knoten gematcht werden, für die kein spezialisierteres Template existiert.

<xsl:template match="@*|*|processing-instruction()|comment()">
    <xsl:copy>
        <xsl:apply-templates select="*|@*|text()|processing-instruction()|comment()"/>
    </xsl:copy>
</xsl:template>

Oder kürzer (aber weniger explizit):

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

In XSLT 3.0 kann der Umgang mit Knoten, für die es keine matchenden Templates gibt mit xsl:mode und @on-no-match, konfiguriert werden. Siehe zu den verfügbaren Werten hier.

<xsl:stylesheet
    /* Snip */
    version="3.0">
    <xsl:output indent="yes" method="xml"/>
    <xsl:mode on-no-match="shallow-copy"/>
</xsl:stylesheet>

Spezifischere Funktionalitäten

XPath-Functions (Auswahl)

In XSLT können die bekannten XPath-Funktionen genutzt werden.

Variables & Parameters (1)

In XSLT können innerhalb eines Templates Variablen gesetzt und abgerufen werden. String-Interpolation erfolgt über 1 {$var_name}.

<xsl:template match="commentary">
    <xsl:variable name="ID" select="ancestor::resource/@id"/>
    <div type="commentary" ancestor="{$ID}"1>
        <xsl:apply-templates select="." />
    </div>
</xsl:template>

Variables & Parameters (2)

In XSLT können 1 Variablen und 2 Parameter gesetzt und innerhalb eines Templates abgerufen werden. Parameter können zudem im xsl:apply-templates an nachfolgende Templates übergeben werden. String-Interpolation erfolgt über {$var_name}.

<xsl:template match="commentary">
<xsl:variable 1 name="ID" select="ancestor::resource/@id"/>
    <div type="commentary">
        <xsl:apply-templates select=".">
            <xsl:with-param 3 name="ID" select="$ID"/>
        </xsl:apply-templates>
    </div>
</xsl:template>

<xsl:template match="sup">
<xsl:param 2 name="ID" />
    <hi rend="superscript">
        <ref xml:id="{$ID}" target="#apparatus_{$ID}"><xsl:apply-templates /></ref>
    </hi>
</xsl:template>
Hinweis: Wenn eine xsl:variable per 3 xsl:with-param in der Rekursion weitergereicht wird, muss sie in nachfolgenden Templates mit xsl:param 2 “gefangen” werden, um nutzbar zu sein. Soll sie in der Rekursion weiter verfügbar sein, muss die Variable zudem erneut im xsl:apply-templates-Aufruf per xsl:with-param weitergegeben werden.

Input & Output (2)

Einbinden externer Dateien

Mit der 1 document()-Funktion können über eine URI (Pfad im Dateisystem, URL zu einer Web-Ressource) in den laufenden XSL-Prozess einbezogen werden.

Die per document() eingebundene Datei kann durch weitere Templates und Funktionen weiterverarbeitet werden.

<xsl:template match="person">
    <person>
    <name><xsl:value-of select="persName" /></name>
    <pre>
    <code>
    <xsl:copy-of 1 select="document(concat('https://lobid.org/gnd/',@gnd,'.rdf'))/node()" />
    </code>
    </pre>
    </person>
</xsl:template>
Wichtig: Beim Einbinden und Verarbeiten externer Ressourcen muss darauf geachtet werden, gegebenenfalls neu auftretende Namespaces adäquat zu verarbeiten.

Conditional Flow

In XSLT können einfache und komplexe Conditionals gesetzt werden:

<xsl:template match="person">
    <p class="person">
    1<xsl:if test="@title">
            <span class="title"><xsl:value-of select="@title" /></span>
        </xsl:if>
        <xsl:text> </xsl:text>
        <xsl:apply-templates select="." />
        2<xsl:choose>
            3<xsl:when test="@gender = 'male'">
                <xsl:text> (♂)</xsl:text>
            </xsl:when>
            4<xsl:when test="@gender = 'female'">
                <xsl:text> (♀)</xsl:text>
            </xsl:when>
            5<xsl:otherwise>
                <xsl:text> (?)</xsl:text>
            </xsl:otherwise>
        </xsl:choose>
    </p>
</xsl:template>

Custom Functions

In XSLT können innerhalb eines Templates Funktionen erstellt und aufgerufen werden.

<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    …
    3 xmlns:functx="http://www.functx.com" …/>
    …
<xsl:function 3 name="functx:substring-after-match" 1 as="xs:string?">
    <xsl:param name="arg" 1 as="xs:string?"/>
    <xsl:param name="regex" as="xs:string"/>
    2 <xsl:sequence select="replace($arg,concat('^.*?',$regex),'')"/>
</xsl:function>

Siehe auch Artikel auf Data2Type.

Element & Attribute Constructors

Man erstellt …

<xsl:template match="person">
1 <xsl:element name="name">
        2<xsl:attribute name="norm_data">
            3<xsl:value-of select="@gnd"/>
        </xsl:attribute>
        4<xsl:value-of select="persName"/>
    </xsl:element>
</xsl:template>

Rawtext Input

# Headline

I’am a paragraph.

## Second Order Headline

I am a paragraph as well.

Rawtext Input

<xsl:template match="/">
2 <xsl:variable name="rawtext_input" select="unparsed-text('rawtext.md')" 1/>
        <root>
            <xsl:for-each select="tokenize($rawtext_input, '&#xa;')" 3>
                <xsl:variable name="line" select="normalize-space(.)"/>
            4 <xsl:choose>
                    <xsl:when test="starts-with($line, '#')">
                        <xsl:element name="h{string-length(substring-before($line, ' '))}">
                            <xsl:value-of select="normalize-space(substring-after($line, ' '))"/>
                        </xsl:element>
                    </xsl:when>
                    <xsl:when test="$line != ''">
                        <xsl:element name="p">
                            <xsl:value-of select="$line"/>
                        </xsl:element>
                    </xsl:when>
                    <xsl:otherwise/>
                </xsl:choose>
            </xsl:for-each>
        </root>
    </xsl:template>

Output:

<root>
        <h1>Headline</h1>
        <p>I’am a paragraph.</p>
        <h2>Second Order Headline</h2>
        <p>I am a paragraph as well.</p>
    </root>

F I N I S

Thank you

Literature & Software

Literatur

Download