Einbetten von XSLT-Transformationen in Python

(Auszug aus "Python & XML" von Christopher A. Jones & Fred L. Drake, Jr.)

XML wird oft dazu benutzt, den »Kern« eines Dokuments zu speichern, während Transformationen dazu verwendet werden, die Daten in andere Systeme zu integrieren. Sie könnten z. B. eine Bestellung als XML über das Web erhalten und sie in mehrere verschiedene Richtungen (und in verschiedenen Formaten) an Ihre anderen Datenverarbeitungssysteme weiterleiten. Sie könnten das XML parsen, um Daten in Oracle-Tabellen einzufügen, es nach HTML transformieren, es einer internen Website hinzufügen, die Bestellung in eine andere Art von XML transformieren und sie an Ihre Zulieferer weitergeben.

Unabhängig davon, wohin Sie Ihr XML schicken, ist die Möglichkeit, XSLT-Transformationen zur Laufzeit vorzunehmen, von entscheidender Bedeutung. Das 4XSLT-Paket funktioniert sehr schön innerhalb Ihrer Python-Programme. In diesem Abschnitt erstellen wir in Python ein ausführbares CGI (Common Gateway Interface)-Programm zur Verwendung unter Linux und Apache bzw. auf jedem Webserver, der so konfiguriert ist, daß er externe CGI-Programme erlaubt.

An diesem Vorgang sind zwei Stylesheets, ein XML-Dokument und ein ausführbares CGI-Programm beteiligt. Das erste Stylesheet konvertiert das XML-Dokument in HTML für Ihren Browser. Das zweite konvertiert es ebenfalls in HTML für Ihren Browser, fügt jedoch zusätzlichen HTML-Code hinzu, der es Ihnen ermöglicht, den Text des XML-Dokuments zu editieren und ihn auf dem Server zu aktualisieren. Das CGI-Skript in Python ist dazu da, das XML abhängig von Ihren Aktionen mit dem passenden Stylesheet auszuführen. Das Skript kümmert sich ebenfalls um die Aktualisierung der XML-Quelle auf der Festplatte. Damit das Skript korrekt arbeitet, muß es sich in einem Verzeichnis befinden, in dem der Webbenutzer (entspricht dem Benutzer nobody bei Apache und Unix) das Recht hat, eine neue XML-Datei zu schreiben.

Erzeugen der XML-Quellen

Zuerst müssen wir ein XML-Dokument erzeugen. Spätere Aktualisierungen des XML-Codes können durch den Webbrowser erfolgen, nachdem Sie das CGI-Skript erstellt haben. Im Moment kommen wir mit dem folgenden Code aus, der auf der Festplatte als story.xml gespeichert ist:

<?xml version="1.0"?>
<story>
  <title>...</title>
  <body>
    ...
  </body>
</story>

Vergewissern Sie sich, das Dokument als story.xml abzuspeichern, damit das CGI-Skript es finden kann, wenn es die Stylesheets anwendet.

Erzeugen eines einfachen Stylesheets

Das erste Stylesheet, das vom CGI-Skript benutzt wird, zeigt das XML als einfaches HTML im Browser an. Es benutzt die Methode apply-templates von XSLT und enthält einen Formular-Button mit der Aufschrift Editieren, der das CGI-Skript erneut lädt. Wenn das CGI im Editiermodus ausgeführt wird, benutzt es das zweite Stylesheet, um das Editierformular anzuzeigen. Das einfache Stylesheet wird im folgenden Beispiel gezeigt.

Beispiel: story.xsl

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
  <xsl:template match="story">
    <html>
      <head><title>Die Story-Seite</title></head>
      <body><xsl:apply-templates/></body>
    </html>
  </xsl:template>  
  <xsl:template match="title">
    <h1><xsl:apply-templates/></h1>
  </xsl:template>  
  <xsl:template match="body">
    <p><xsl:apply-templates/></p>
    <p>
      <form action="xslt.cgi" method="get">
        <input type="hidden" name="mode" value="edit"/>
        <input type="submit" value="Editieren"/>
      </form>
    </p>
  </xsl:template>  
</xsl:stylesheet>

Die folgende Abbildung zeigt das transformierte XML innerhalb eines Webbrowsers.

Transformation mit einem einfachen Stylesheet

Abbildung: Transformation mit einem einfachen Stylesheet

Erzeugen eines Stylesheets mit Editier-Funktionen

Das zweite Stylesheet ist ähnlich zum ersten, außer daß diesmal der XML-Inhalt in Formularfelder eingesetzt wird, die in Ihrem Browser editiert werden können. Wenn das Formular abgeschickt wird, aktualisiert das CGI-Skript die XML-Datei auf der Platte und führt darauf erneut das einfache Stylesheet aus, um das Resultat erneut zum Browser zu schicken.

Das Stylesheet zum Editieren wird im nächsten Beispiel gezeigt. Es muß als edstory.xsl gespeichert werden.

Beispiel: edstory.xsl

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">  
  <xsl:template match="story">
    <html>
      <head><title>Die Story-Seite</title></head>
      <body>
        <form action="xslt.cgi" method="get">
          <xsl:apply-templates/>
        </form>
      </body>
    </html>
  </xsl:template>  
  <xsl:template match="title">
    <h1><xsl:value-of select="."/></h1>
    <p>Neuer Titel: <input type="text" name="title" length="20"/></p>
  </xsl:template>  
  <xsl:template match="body">
    <p>Neuer Text: 
      <textarea rows="10" cols="50" name="body"><xsl:value-of select="."/></textarea>
      <input type="hidden" name="mode" value="change"/>
      <p><input type="submit" value="Abschicken"/></p>
    </p>
  </xsl:template>  
</xsl:stylesheet>

Die folgende Abbildung zeigt das Editierformular, wie es in einem Webbrowser dargestellt wird. Das Drücken des Abschicken-Buttons aktualisiert die XML-Datei auf der Platte und wendet die einfache Transformation erneut an.

XML innerhalb eines Webbrowsers editieren

Abbildung: XML innerhalb eines Webbrowsers editieren

Erzeugen des CGI-Skripts

Das Skript xslt.cgi faßt die Stylesheets zusammen und koordiniert die Verarbeitung und Aktualisierung des XML-Codes auf der Festplatte. Obwohl diese Anwendung Ihnen das Editieren und Anzeigen von XML in Ihrem Browser gestattet, besteht es nur aus einem CGI-Skript und zwei XSL-Sheets. Quelldaten, die sich vielleicht ständig ändern, werden ebenfalls als XML auf der Platte gespeichert.

XSLT-Transformationen können mit der Klasse xml.xslt.processor.Processor programmatisch vorgenommen werden (vorausgesetzt, 4XSLT wurde wie vorher angegeben installiert). Wenn das CGI-Skript startet, importiert und instanziiert es den XSLT-Prozessor:

#!/usr/local/bin/python
# xlst.cgi

import cgi
import os
import sys

from xml.xslt.Processor import Processor

# Parse Abfrage-String & instanziiere XSLT-Prozessor
query = cgi.FieldStorage( )

xsltproc = Processor( )

Die Verwendung des XSLT-Prozessors im CGI-Skript erweist sich als einfach. Es werden zwei Methoden verwendet, um ein Stylesheet zu bestimmen und eine Transformation auszuführen, die das Ergebnis als String zurückgibt:

xsltproc.appendStylesheetUri("story.xsl")
html = xsltproc.runUri("story.xml")

Mit der Methode appendStylesheetUri wird festgelegt, welches Stylesheet bei einer Transformation benutzt wird. Die Methode runUri führt dann die Transformation auf einem XML-Quelldokument aus und gibt das Ergebnis als String zurück.

Das CGI-Skript nimmt keinerlei Transformationen vor, bevor es nicht weiß, was Sie eigentlich vorhaben. Ihre Wahl wird dem Skript mit Hilfe eines Abfrage-Strings mitgeteilt, der dem Server als Teil der Anfrage übergeben wird.

Auswählen eines Modus

Nachdem sich das CGI-Skript den QUERY_STRING geholt hat, wird daraus der Modus bestimmt (Editieren, Ändern oder Anzeigen), den Sie ausgewählt haben. Haben Sie nichts dergleichen angegeben, gibt das Skript eine Beschwerde zurück und beendet:

mode = query.getvalue("mode", "")
if not mode:    
    print "<html><body>"
    print "<p>Kein Modus angegeben</p>"
    print "</html></body>"
    sys.exit(0)

Im Falle eines show-Befehls werden das einfache Stylesheet und die XML-Quelle vom XSLT-Prozessor geladen, und das resultierende HTML wird an den Browser übergeben:

if mode[0] == "show":   
   # Wende einfaches Stylesheet auf XML an
   xsltproc.appendStylesheetUri("story.xsl")
   html = xsltproc.runUri("story.xml")
   print html

Bei einem edit-Befehl wird das XML mit dem Editier-Stylesheet bearbeitet, das die notwendigen Formular-Auszeichnungen hinzufügt. Das ist fast identisch zum show-Befehl, aber der Name des Stylesheets ist verschieden.

elif mode[0] == "edit":   
   # Wende formularbasiertes Stylesheet auf XML an
   xsltproc.appendStylesheetUri("edstory.xsl")
   html = xsltproc.runUri("story.xml")
   print html

Wenn Sie den Abschicken-Button drücken würden, nachdem Sie das XML editiert haben, würde das Resultat zusammen mit einem change-Befehl zum Server geschickt. Das Skript würde dann die XML-Datei auf der Platte aktualisieren, die Transformation erneut anwenden und das Ergebnis an Ihren Browser zurückschicken.

elif mode[0] == "change":    
    # Ändere XML-Quelldatei, wiederhole Stylesheet und zeige an
    newXML = '<?xml version="1.0"?>\n'
    newXML += "\t<story>\n\t<title>"
    newXML += query.getvalue("title")[0] + "</title>\n"
    newXML += "\t<body>\n"
    newXML += query.getvalue("body")[0] + "\n\t</body>\n</story>\n"
    fd = open("story.xml", "w")
    fd.write(newXML)
    fd.close( )

    # Führe aktualisiertes XML mit einfachem Stylesheet aus
    xsltproc.appendStylesheetUri("story.xsl")
    html = xsltproc.runUri("story.xml")
    print html

Falls das Skript keine Schreibrechte hat, wenn es unter dem Webbenutzer ausgeführt wird, schlägt es fehl.

Das folgende Beispiel zeigt das komplette Listing von xslt.cgi.

Beispiel: xslt.cgi

#!/usr/local/bin/python
# xlst.cgi

import cgi
import os
import sys

from xml.xslt.Processor import Processor

# Parse Abfrage-String & instanziiere xslt-Prozessor
query = cgi.FieldStorage( )

xsltproc = Processor( )

print "Content-type: text/html\r\n"

mode = query.getvalue("mode", "")   
if not mode:
   print "<html><body>"
   print "<p>Kein Modus angegeben</p>"
   print "</html></body>"
   sys.exit( )

if mode[0] == "show":
   # Führe XML mit einfachem Stylesheet aus
   xsltproc.appendStylesheetUri("story.xsl")
   html = xsltproc.runUri("story.xml")
   print html

elif mode[0] == "change":
   # Ändere XML-Quelldatei, wiederhole Stylesheet und zeige an
   newXML = '<?xml version="1.0"?>\n'
   newXML += "\t<story>\n\t<title>"
   newXML += query.getvalue("title")[0] + "</title>\n"
   newXML += "\t<body>\n"
   newXML += query.getvalue("body")[0] + "\n\t</body>\n</story>\n"
   fd = open("story.xml", "w")
   fd.write(newXML)
   fd.close( )

   # Führe aktualisiertes XML mit einfachem Stylesheet aus
   xsltproc.appendStylesheetUri("story.xsl")
   html = xsltproc.runUri("story.xml")
   print html

elif mode[0] == "edit":
   # Führe XML mit formularbasiertem Stylesheet aus
   xsltproc.appendStylesheetUri("edstory.xsl")
   html = xsltproc.runUri("story.xml")
   print html

  

<< zurück vor >>

 

 

 

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

Copyright © 2002 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 "Python & 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