XML, XPath & XSLT
Jun.-Prof. Dr. Mark Hall
Wintersemester 2018/19
SGML
SGML - Structured Generalized Markup Language
Hierarchische Annotation des Texts mit Tags die Konzepte spezifizieren
XML
Untermenge der in SGML gültigen Strukturen
Hat heutzutage SGML ersätzt
Ist eine Meta-sprache, definiert also selbst keine Tags
Element
<element>
</element>
<element>
Inhalt
</element>
<element>
</element>
<element>
</element>
XML Dokumente bestehen aus Elementen.
Ein Element besteht normalerweise aus einem öffnenden und einem schließenden Tag.
Tags werden in spitze Klammern eingeschlossen <...>.
Der schließende Tag wird durch einen Schrägstrich definiert /.
Der erste Text im Tag ist der Name des Tags.
Tags sind generell eher kleingeschrieben
Der Inhalt zwischen den zwei Tags wird als der Inhalt des Elements bezeichnet
Mehrere Elemente können den gleichen Tag verwenden
Leere Elemente
<element/>
Bei Elementen die keinen Inhalt haben kann der schließende / direkt in den öffnenden Tag inkludiert werden
Verschachtelte Elemente
<parent>
<child></child>
</parent>
Elemente können in XML inneinander geschachtelt werden.
Ein XML Dokumente darf am obersten Level nur ein Element haben.
XML DOM
<ancestor>
<parent>
<previous>
</previous>
<element>
<child>
<descendant>
</descendant>
</child>
</element>
<next>
</next>
<sibling>
</sibling>
</parent>
</ancestor>
Die Verschachtelung definiert eine Baumstruktur
Diese Baumstruktur wird als Document Object Model (DOM) bezeichnet
Elemente im DOM haben bestimmte Namen (relativ zu dem "element"):
Parent: Das Element das das aktuelle Element direkt enthält
Ancestor: Alle Elemente die das aktuelle Element direkt oder in mehreren Verschachtelungen enthalten
Child: Elemente die vom aktuellen Element direkt enthalten werden
Descendant: Elemente die vom aktuellen Element direkt oder in mehreren Verschachtelungen enthalten werden
Previous: Das Element das direkt vor dem aktuellen Element steht und den gleichen Parent hat
Next: Das Element das direkt nach dem aktuellen Element steht und den gleichen Parent hat
Sibling: Alle Elemente die den gleichen Parent haben (beinhaltet auch next und previous)
Attribute
<element attribute-name="attribut-wert"/>
<element attribute-name1="attribut-wert1" attribute-name2="attribut-wert2"/>
Elemente können auch mit Attributen versehen werden
Attribute sind immer als Name-Wert Paare definiert
Der Name darf nur aus Buchstaben, Zahlen, _, und - bestehen und muss mit einem Buchstaben beginnen
Der Wert ist immer zwischen Anführungszeichen "..." zu setzen
Attribute werden vom Elementnamen und voneinander mittels Leerzeichen getrennt
Text
Dies ist ein <note>besonderer</note> Text
<element1></element1>
<element2></element2>
Text ist alles was nicht Tag oder Attribute ist
Auch der Zeilenumbruch und Leerzeichen zwischen Elementen sind Text
Validität
DTD - Document Type Definition
XML-Schema
Ein XML Dokument ist gültig, wenn es den Regeln des definierenden Schemas folgt
DTD ist eine relativ einfache Struktur die definiert welche Tags welche anderen Tags beinhalten dürfen,
welche Tags Text haben können, und welche Tags welche Attribute haben können
XML Schema ist eine komplexere Schemadefinitionssprache, welche selbst in XML kodiert wird. XML Schema hat
ein vollständiges Typsystem und erlaubt es zwischen dem Typ und der Instanz eines Typs in der Definition
zu unterscheiden.
XPath
/
/element
/element/child
//element-irgendwo-im-baum
/element@attribut
/element::text()
/element[@attribut=wert]
//element[1]
XPath ist eine Abfragesprache um Elemente aus dem XML DOM auszuwählen
XPath ist primär eine Reihe von Knoten die den Pfad tiefer ins Dokument definiert
Auch die Auswahl von Attribut-werten oder Text eines Elements sind möglich
Jede XPath Abfrage liefert (potentiell) eine Liste and Ergebnissen, es wird nicht nur der erste Match gefunden
Abfragen können auch Bedingungen haben bezüglich Attributwerte oder welches Element aus einer Ergebnisliste zurückgegeben wird
XSLT
<xsl:template match="element">
<text><xsl:value-of select="text()"/></text>
</xsl:template>
<element>Dies ist der Text</element>
<text>Dies ist der Text</text>
Das Grundelement der XSLT codierung ist das "Template"
Ein Template definiert über das "match" attribute einen XPath der die Elemente auf die das Template angewendet werden kann festlegt
Bei relativen XPath Pfaden, wird der match relativ zum aktuellen Element ausgeführt. Das ist zuerst das Dokument als ganzes, kann
später aber auch ein Element tiefer im DOM sein
Tags innerhalb des Template definieren den Output, wobei value-of verwendet werden kann um einen Wert, ausgehend vom gematchten Element,
zu selektieren
XSLT
<document>
<element>Element 1</element>
<element>Element 2</element>
</document>
<xsl:template match="element">
<text><xsl:value-of select="text()"/></text>
</xsl:template>
<text>Element 1</text>
<text>Element 2</text>
Da im ersten Schritt Templates auf das Dokument als ganzes gematcht werden, greift die Regel nicht
Man könnte das "match" so ändern, dass es direkt auf die Element zugreift, aber das sollte man vermeiden
Das schöne an XSLT ist dass es eine Defaultregel hat, welche, wenn kein Template matched, einfach
rekursiv alle Templates auf alle Kinderelemente anwendet
XSLT verläßt sich stark auf diese Art der Rekursion
Wichtig! Eine XSLT Transformation muss nicht unbedingt ein wohlgeformtes XML Dokument als Ergebnis haben
XSLT
<geschichte>
<titel>Eine kleine Geschichte</titel>
<absatz>Dies ist der Anfang</absatz>
<absatz stil="einruecken">Und so geht es weiter</absatz>
</geschichte>
<xsl:template match="/">
<html>
<body>
<xsl:apply-templates></xsl:apply-templates>
</body>
</html>
</xsl:template>
<xsl:template match="absatz">
<p><xsl:apply-templates></xsl:apply-templates></p>
</xsl:template>
<xsl:template match="absatz[@stil='einruecken']">
<p class="indent"><xsl:apply-templates></xsl:apply-templates></p>
</xsl:template>
<html>
<body>
<p>Dies ist der Anfang</p>
<p class="indent">Und so geht es weiter</p>
</body>
</html>
Um immer ein gültiges XML Dokument zu generieren ist eine Regel die auf den Wurzelknoten matched und dann
dort ein neues Wurzelelement generiert am besten
Im zweiten Schritt würde das "select" die zwei "absatz" Tags matchen und versuchen alle Templates auf diese anzuwenden.
Für beide Tags würden beide Templates matchen, der XSLT Processor muss da jetzt entscheiden welches der
Templates zu verwenden. Dies passiert aufgrund der Spezifizität des XPath im "match". Es wird immer das
spezifischte Template angewandt.
XSLT
<hi rend="bold">Fett und <hi rend="italic">Fett-Kursiv</hi></hi>
<xsl:template match="//hi[@rend='bold']">
<span class="bold"><xsl:value-of select="text()"/></span>
</xsl:template>
<xsl:template match="//hi[@rend='italic']">
<span class="italic"><xsl:value-of select="text()"/></span>
</xsl:template>
<span class="bold">Fett und Fett-Kursiv</span>
XSLT
<hi rend="bold">Fett und <hi rend="italic">Fett-Kursiv</hi></hi>
<xsl:template match="hi[@rend='bold']">
<span class="bold"><xsl:apply-templates></xsl:apply-templates></span>
</xsl:template>
<xsl:template match="hi[@rend='italic']">
<span class="italic"><xsl:apply-templates></xsl:apply-templates></span>
</xsl:template>
<span class="bold">Fett und <span class="italic">Fett-Kursiv</span></span>
Der rekursive Ansatz unterstützt beliebige Schachtelung der Inputdaten
XSLT hat generell ein Defaulttemplate welches jeden Text einfach ausgiebt
Literatur
Köhler, W., Wittenbrink, H., & Bormann, C. (2003). XML. Berlin TEIA-Lehrbuch-Verlag.
Kay, M. (2008). XSLT 2.0 and XPath 2.0: Programmer’s reference. Ind. Wiley.