XSL Transformations (XSLT)

Die Transformation von XML-Daten in ein anderes Format, das beispielweise HTML oder PDF sein kann, ist aus der Entwicklung von Web-Applikationen kaum noch wegzudenken. Für diese Aufgabe bietet das World Wide Web Consortium die eXtensible Stylesheet Language (XSL) an. Diese besteht aus den drei Komponenten:

  • XSL Transformations (XSLT) bildet die eigentliche Programmiersprache zur Beschreibung von XML-Transformationen.

  • Die XML Path Language (XPath) wird von XSLT genutzt, um auf XML-Dokumente beziehungsweise Teile davon zuzugreifen.

  • XSL Formatting Objects (XSL-FO) werden genutzt, um Formatierungen zu beschreiben.

Vom Arbeitsprinzip her ist XSLT mit dem UNIX-Werkzeug awk verwandt: Bedingungen (Template Match) oder Funktionen (Template Name) werden nacheinander auf die Eingabe angewendet. Diese hat bei awk Zeilen, bei XSLT liegt sie als Baumstruktur vor. Wie awk kann XSLT nicht auf seine Ausgabe zugreifen.

Beispiel 8.18: if-then-else in XSLT


<xsl:template match="/">
  <xsl:choose>
    <xsl:when test="$foobar = 'foo'">
      <xsl:call-template name="foo"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:call-template name="bar"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>



Stylesheets, wie in XSLT geschriebene Programme aus historischen Gründen heißen, sind ihrerseits XML-Dokumente. Daher ist XSLT "geschwätzig", das heißt, sogar einfache Sprachkonstrukte erfordern viel Schreibarbeit. Beispiel 8.18 zeigt oben den nötigen Code, um ein if-then-else in XSLT zu realisieren, unten das hierzu äquivalente PHP-Schnipsel in Beispiel 8.19.

Beispiel 8.19: if-then-else in PHP

<?php
if ($foobar == 'foo') foo() else bar();
?>


Wie die Document Style Semantics and Specification Language (DSSSL) für SGML ist XSLT eine funktionale Transformationssprache. Sie bringt daher die Nachteile funktionaler Programmiersprachen mit sich, beispielsweise den Umweg über Rekursion für das Ausdrücken von Schleifen oder Variablen, die eher konstant als variabel sind. Außerdem kann man die Vorteile der funktionalen Programmierung, etwa das Rechnen mit Funktionen als Datentypen oder die Programmierung mit Closures, nicht nutzen. Die bietet XSLT nicht.

Ein weiterer Nachteil von XSLT liegt in der Domänenbeschränkung: Während XSLT "alles über XML weiß" und diesbezügliche Funktionen anbietet, weiß es relativ wenig von Dingen, die nichts mit XML zu tun haben. Ohne die Einbeziehung von in anderen Programmiersprachen, beispielsweise Java, geschriebenen Programmen über Callbacks können XSLT-Stylesheets nicht mit der Welt jenseits von XML interagieren. Das Beziehen von Daten aus anderen Quellen wie einer Datenbank oder das Erzeugen von nicht textbasierten Ausgabeformaten wie Grafiken oder PDF ist ohne Fremdhilfe nicht möglich.

Die PHP-Programmierschnittstelle für XSLT

Abbildung 8.4. Die Klasse XSLTProcessor

Die Klasse XSLTProcessor


PHP 5 bietet, angelehnt an die Programmierschnittstelle des Mozilla-Projektes, die Klasse XSLTProcessor (Abbildung 8.4) für die Ausführung von XSL-Transformationen an. Im Gegensatz zu den bereits vorgestellten XML-Programmierschnittstellen von PHP 5 ist die XSLT-Erweiterung in der Standardkonfiguration nicht aktiviert. Sie muss über --with-xsl bei der Konfiguration des Build-Prozesses aktiviert werden (siehe Anhang A).

Mit DOMDocument::load() werden in Beispiel 8.21 zunächst XML-Dokument (Beispiel 8.1) und XSL-Stylesheet (Beispiel 8.20) in je ein Objekt der Klasse DOMDocument geladen. Mit den Methoden importStylesheet() und transformToDoc() wird das XSL-Stylesheet-Objekt einem XSLT-Prozessor-Objekt zugewiesen sowie das Eingabedokument in ein neues Objekt der Klasse DOMDocument transformiert.

Beispiel 8.20: XSL Stylesheet für den Buchkatalog


<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html" />
  <xsl:template match="/">
    <html>
      <body>
        <ul>
          <xsl:for-each select="books/book">
            <li>
              <xsl:value-of select="author" /><br />
              <xsl:value-of select="title" /><br />
              ISBN: <xsl:value-of select="isbn" /><br />
            </li>
          </xsl:for-each>
        </ul>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>



Beispiel 8.21: Transformation des Buchkatalogs von XML nach HTML mit XSLT

<?php
$document   = DOMDocument::load('books.xml');
$stylesheet = DOMDocument::load('books.xsl');
 
$processor = new XSLTProcessor;
$processor->importStylesheet($stylesheet);
 
print $processor->transformToDoc($document)->saveXML();
?>
<?xml version="1.0" standalone="yes"?>
<html>
  <body>
    <ul>
      <li>
        Sebastian Bergmann<br/>
        Professionelle Softwareentwicklung mit PHP 5<br/>
        ISBN: 3-89864-229-1<br/>
      </li>

      <li>
        Hakan Kücükyilmaz<br/>
        PHP 5<br/>
        ISBN: 3-89864-236-4<br/>
      </li>
    </ul>
  </body>
</html>


Alternativ stehen die Methoden transformToUri() und transformToXml() zur Verfügung, die das Transformationsergebnis in einer Datei abspeichern oder als String zurückliefern.

Die Parameter des XSL-Stylesheets können über die Methoden getParameter(), setParameter() und removeParameter() kontrolliert werden.

Aufrufen von PHP-Funktionen aus XSLT heraus

Über die XSL-Funktion php:function können beliebige PHP-Funktionen aus einem XSL-Stylesheet heraus aufgerufen werden. Dieser muss hierfür mit xmlns:php="http://php.net/xsl" den entsprechenden Namespace deklarieren (Beispiel 8.22). Über die Methode registerPHPFunctions() des XSLT-Prozessor-Objektes wird die Unterstützung für die Ausführung von PHP-Funktionen in XSL-Stylesheets aktiviert (Beispiel 8.23).

Beispiel 8.22: Verwendung einer PHP-Funktion in einem XSL-Stylesheet


<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:php="http://php.net/xsl" version='1.0'>
  <xsl:template match="/">
    <xsl:value-of select="php:function('str_rot13', 'CUC 5')"/>
  </xsl:template>
</xsl:stylesheet>



Beispiel 8.23: Transformation mit einem XSL-Stylesheet, das eine PHP-Funktion verwendet

<?php
$stylesheet = DOMDocument::load('php_function.xsl');
 
$processor = new XSLTProcessor;
$processor->registerPHPFunctions();
$processor->importStylesheet($stylesheet);
 
$result = $processor->transformToDoc(new DOMDocument);
print $result->saveXML();
?>
PHP 5