Transformationen

(Auszug aus "Perl & XML" von Erik T. Ray & Jason McIntosh)

Das letzte Thema, auf das wir in diesem Abschnitt eingehen wollen, ist das Konzept der Transformation. In XML versteht man unter Transformation den Prozeß der Restrukturierung eines Dokuments oder sogar dessen Umwandlung in eine gänzlich andere Form. Das W3C empfiehlt dafür eine spezielle Transformationssprache namens XML Stylesheet Language for Transformations (XSLT). Mit dieser Technologie zu arbeiten ist unglaublich nützlich und erfreulich einfach.

Wie im Fall eines XML Schemas ist auch das Transformationsskript von XSLT selbst ein XML-Dokument. Das Skript besteht aus sogenannten Templates oder Templateregeln . Jedes Template enthält eine Anweisung, ein bestimmtes Element in etwas anderes umzuwandeln. Die Bezeichnung Template wird oft verwendet, um anzugeben, wie etwas auszusehen hat. Dabei gibt es normalerweise markierte Stellen, an denen irgend etwas einzufügen ist. Nach genau diesem Prinzip arbeiten auch die Templateregeln von XSLT: Sie definieren Beispiele, wie das Endergebnis auszusehen hat, und überlassen es dem XSLT-Prozessor, bestimmte Stellen auszufüllen.

Das folgende Beispiel ist eine rudimentäre Transformation, die ein einfaches XML-Dokument für DocBook in eine HTML-Seite umwandelt.

Beispiel: Ein Transformationsskript für XSLT

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="html"/>
  <!-- Regel für das Element "book" -->
  <xsl:template match="book">
    <html>
      <head>
        <title><xsl:value-of select="title"/></title>
      </head>
      <body>
        <h1><xsl:value-of select="title"/></h1>
        <h3>Inhaltsverzeichnis</h3>
        <xsl:call-template name="inhaltsverzeichnis"/>
        <xsl:apply-templates select="chapter"/>
      </body>
    </html>
  </xsl:template>
  <!-- Regel für "chapter" -->
  <xsl:template match="chapter">
    <xsl:apply-templates/>
  </xsl:template>
  <!-- Regel für den Titel eines Kapitels -->
  <xsl:template match="chapter/title">
    <h2>
      <xsl:text>Kapitel </xsl:text>
      <xsl:number count="chapter" level="any" format="1"/>
    </h2>
    <xsl:apply-templates/>
  </xsl:template>
  <!-- Regel für "para" (Absatz) -->
  <xsl:template match="para">
    <p><xsl:apply-templates/></p>
  </xsl:template>
  <!-- Regel mit Namen: "inhaltsverzeichnis" -->
  <xsl:template name="toc">
    <xsl:if test="count(chapter)>0">
      <xsl:for-each select="chapter">
        <xsl:text>Kapitel </xsl:text>
        <xsl:value-of select="position( )"/>
        <xsl:text>: </xsl:text>
        <i><xsl:value-of select="title"/></i>
        <br/>
      </xsl:for-each>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>
    

Zunächst liest der XSLT-Prozessor das Stylesheet und erzeugt eine interne Tabelle mit Templateregeln. Als nächstes untersucht er das ursprüngliche XML-Dokument (das transformiert werden soll) und durchläuft es Knoten für Knoten. Ein Node oder Knoten ist ein Element, ein Stück Text, eine Verarbeitungsanweisung (PI), ein Attribut oder die Deklaration eines Namensraums. Für jeden Knoten versucht der XSLT-Prozessor die am besten passende Regel zu finden. Die Regel wird auf den Knoten angewandt, indem das Template mit eventuellen Ersetzungen anstelle des Knotens ausgegeben wird.

Das Beispiel unten ist ein Beispieldokument, mit dem man die Transformation ausprobieren kann.

Beispiel: Ein transformierbares Dokument

<?xml version="1.0" encoding="iso-8859-1"?>
<book>
  <title>Ein diabolischer Verstand</title>
  <chapter>
    <title>Im Basar</title>
    <para>Was für ein wunderbarer Tag das war! In den Ständen türmten sich die
      verschiedensten importierten Güter: Datteln, Bananen, Trockenfrüchte,
      feinste Seide und mehr als ich beschreiben kann. Als ich umherlief
      und die Düfte von frischem Kaffe, gewürztem Wein und Kardamom genoß,
      hätte ich beinahe einen unauffälligen, fahrbaren Stand übersehen, an
      dem ein kleiner Mann Gehirne verkaufte.</para>
    <para>Gehirne! Ja, menschliche Gehirne, grau und etwas aufgequollen, aber
      gut erhalten und in großen Glasgläsern schwimmend, die mit einer
      grünlichen Flüssigkeit gefüllt waren.</para>
    <para>"Möchten Sie gerne ein Gehirn versuchen, mein Herr?" fragte er. "Sie
      sind heute sehr preisgünstig. Hier ist das von Heisenberg, nur zwei
      Euro! Oder bevorzugen Sie Kant? Falls Sie es etwas pompöser mögen,
      wäre Ihnen vielleicht der große Kurfürst recht?"</para>
    <para>Ich fuhr entgeistert zurück...</para>
  </chapter>
</book>

Gehen wir die Transformation Schritt für Schritt durch.

  1. Das erste Element ist <book>. Die am besten dazu passende Regel ist gleich die erste, da sie ausdrücklich für »book« gemacht ist. Das Template sieht vor, daß Tags wie <html>, <head> oder <title> auszugeben sind. Beachten Sie, daß diese Tags wie Daten behandelt werden, da sie nicht das Präfix xsl: tragen.
  2. Wenn der Prozessor zu der XSLT-Anweisung <xsl:value-of select="title"/> kommt, dann sucht er nach einem Element <title>, das ein Kind des aktuellen Elements <book> sein muß. Hat er es gefunden, dann bestimmt er den Wert (value) dieses Elements. Dabei handelt es sich einfach um den gesamten textuellen Inhalt. Das Template sieht vor, diesen Text innerhalb eines Elements <title> auszugeben.
  3. Der Prozessor fährt in derselben Art und Weise fort, bis er die Anweisung <xsl:call-template name="toc"/> findet. Wenn Sie an das Ende des Stylesheets schauen, dann finden Sie eine Templateregel, die mit <xsl:template name="inhaltsverzeichnis"> beginnt. Dabei handelt es sich um ein benanntes Template , das die Funktion eines Funktionsaufrufs erfüllt. Das Template stellt ein Inhaltsverzeichnis zusammen und gibt den generierten Text an die aufrufende Regel zurück, die ihn dann ausgeben kann.
  4. Innerhalb des benannten Template finden wir ein Element namens <xsl:if test="count(chapter)>0">. Dabei handelt es sich um eine bedingte Anweisung. Sie prüft, ob innerhalb des aktuellen Elements (das ist immer noch <book>) wenigstens ein <chapter>-Element vorkommt. Der Test ergibt ein positives Ergebnis, weshalb die Verarbeitung mit dem Inneren der bedingten Anweisung fortfährt.
  5. Die Anweisung <xsl:for-each select="chapter"> veranlaßt den Prozessor, nach allen <chapter> -Elementen zu suchen, die Kinder des aktuellen Elements sind. Der Reihe nach wird jedes dieser Kinder vorübergehend selbst zum aktuellen Element, und das Innere des <xsl:for-each>-Elements wird verarbeitet. Das ist analog zu einer foreach( )-Schleife in Perl. Die Anweisung <xsl:value-of select="position( )"/> ergibt die numerische Position des aktuellen <chapter>-Elements, so daß also »Kapitel 1«, »Kapitel 2« usw. ausgegeben wird.
  6. Das Template mit Namen »inhaltsverzeichnis« übergibt den generierten Text an die aufrufende Regel, und die Verarbeitung wird fortgeführt. Als nächstes erreicht der Prozessor das Element <xsl:apply-templates select="chapter"/> . Wird dieses <xsl:apply-templates> ohne Attribute angewandt, dann heißt das, daß der Prozessor die Kinder des aktuellen Elements durchlaufen soll, um sie nacheinander zum aktuellen Element zu machen. In diesem Fall finden wir aber das Attribut select="chapter". Demzufolge werden nur die Kinder vom Typ <chapter> durchlaufen. Nachdem diese und ihre Ahnen durchlaufen wurden, um Text zu produzieren, wird der generierte Text ausgegeben, und der Rest der Regel wird bis zum Ende ausgeführt.
  7. Der Prozessor fährt mit dem ersten <chapter>-Element fort, sucht nach einer passenden Regel, findet aber nur <xsl:apply-templates/>. Der Rest der Verarbeitung, d. h. die Behandlung von <title> und <para>, ist jetzt offensichtlich.

XSLT ist eine sehr reiche Sprache zur Behandlung von Transformationen. Trotzdem bleiben oft Wünsche offen. Bei der Verarbeitung großer Dokumente kann XSLT sehr langsam werden, da der Prozessor meist erst eine interne Repräsentation des Dokuments aufbaut, bevor er mit der eigentlichen Arbeit beginnt. Obwohl seine Syntax sehr geschickt die Möglichkeiten von XML nutzt, ist sie nicht so ausdrucksstark und einfach anwendbar wie die von Perl. Wir werden noch eine Vielzahl von Beispielen bringen, in denen man statt Perl genausogut XSL benutzen könnte. Sie müssen selbst entscheiden, ob Sie die Einfachheit von XSLT oder die Mächtigkeit und Kraft von Perl anwenden.

Das war unsere Tour durch XML im Schnellverfahren. Als nächstes wollen wir die Basis für die XML-Verarbeitung mit Perl schaffen, indem wir die Arbeit mit in Perl geschriebenen Parsern und die einfache Erzeugung von Dokumenten erklären. Sie sollten jetzt eine gute Vorstellung von dem haben, wofür XML benutzt wird, wofür es gut ist, und Sie sollten alle Teile eines XML-Dokuments erkennen. Wenn Sie dagegen auch jetzt noch unsicher sind, sollten Sie vielleicht besser doch zuerst ein XML- Tutorial lesen.

  

  

<< zurück vor >>

 

 

 

Tipp der data2type-Redaktion:
Zum Thema Perl & XML bieten wir auch folgende Schulungen zur Vertiefung und professionellen Fortbildung an:

Copyright © 2003 O'Reilly Verlag GmbH & Co. KG
Für Ihren privaten Gebrauch dürfen Sie die Online-Version ausdrucken.
Ansonsten unterliegt dieses Kapitel aus dem Buch "Perl & XML" denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

O’Reilly Verlag GmbH & Co. KG, Balthasarstraße 81, 50670 Köln, kommentar(at)oreilly.de