Inhalt
Lies mich zuerst!
Es gibt zwei Möglichkeiten Scheme-Servlets zu entwickeln,
zwischen denen man sich entscheiden muß:
Dr. Scheme als Entwicklungsumgebung
einrichten
Dieser Eintrag ist nur relevant, wenn du dich entschieden
hast die Dr. Scheme Methode zur
Servlet-Entwicklung zu benutzen!
Es sind zwei Schritte notwendig, um Dr. Scheme für die
Servlet-Programmierung vorzubereiten. Beide Einstellungen
müssen nur einmal vorgenommen werden; Dr. Scheme merkt sich
diese Einstellungen.
1. "Language Level" wählen
Dr. Scheme bietet unterschiedliche "Language Level" an, mit
denen bestimmte Features von Scheme abgeschaltet werden
können. Diese Funktion ist jedoch nur im Kontext einer
Lehrveranstaltung für Programmieranfänger sinnvoll. Für die
Programmierung von Servlets muß erst ein entsprechender
"Language Level" gewählt werden. Öffne dazu im Menü
"Language" den Punkt "Choose Language" aus. In dem nun
erscheinenden Dialog findet sich unter dem Punkt "PLT" die
Einstellung "Pretty Big" -- das ist die gesuchte
Einstellung. Ist ein anderer "Language Level" eingestellt,
funktionieren die Servlets (und Beispielprogramme) unter
Umständen nicht!
2. "Teachpacks" installieren
Über die Teachpacks
werden die für die Servlet-Programmierung benötigten
Funktionen direkt in Dr. Scheme geladen. Im Menü "Language"
wird dazu der Punkt "Add Teachpack..." ausgewählt. Es
erscheint ein Fenster zur Dateiauswahl. Als nächstes wird im
Verzeichnis
/afs/informatik.uni-tuebingen.de/share/plt-203/teachpack/htdp
die Datei servlet.ss ausgewählt und nach einem
Klick auf den "Execute"-Button ist das entsprechende
Teachpack installiert. Diesen Vorgang für
servlet2.ss (im selben Verzeichnis) wiederholen.
Servlets
mit Dr. Scheme schreiben und starten
Dieser Eintrag ist nur relevant, wenn du dich entschieden
hast die Dr. Scheme Methode zur
Servlet-Entwicklung zu benutzen!
Ist Dr. Scheme entsprechend
eingerichtet kann die gesamte Servlet-Entwicklung aus
Dr. Scheme heraus vorgenommen werden. Die Beispiele aus der Vorlesung sind
hier ein guter Startpunkt. Drückt man den "Execute"-Button,
so wird das Servlet in den internen Webserver von Dr. Scheme
geladen und ist damit bereit zur Ausführung. Dr. Scheme startet außerdem
einen Browser, der die URL dieses Servlets öffnet.
Den PLT-Webserver für die Kommandozeile
einrichten
Dieser Eintrag ist nur relevant, wenn du dich entschieden
hast die do-it-yourself-Methode zur
Servlet-Entwicklung zu benutzen!
Alternativ zur Servlet-Entwicklung innerhalb von Dr. Scheme
können Servlets auch von Hand in den PLT-Webserver
eingebracht und gestartet werden. Dies ist eine Alternative
für Benutzer, die auf keinen Umständen auf ihren
Lieblingstexteditor verzichten wollen. Für Scheme-Einsteiger
ist die Entwicklung innerhalb von
Dr. Scheme zu empfehlen.
Der PLT-Webserver muß einmal eingerichtet werden. Dazu
müssen die entsprechenden Dateien in dein Home-Verzeichnis
kopiert werden:
cp -R /afs/wsi/share/plt-203/collects/web-server/default-web-root ~/plt-webAlle Dateien, die in ~/plt-web/htdocs liegen, stellt der Web-Server nun per HTTP zur Verfügung.
cp /afs/wsi/pu/pfi-2002/share/plt-web-server-conf.scm ~/plt-web/webserver-conf.scmErsetze nun alle Vorkommen des Strings HIER-DEIN-LOGIN durch deinen WSI-Login. Nun kann der Server gestartet werden:
web-server -f ~/plt-web/webserver-conf.scmDer Webserver startet nun und horcht auf Port 8001. Mit Ctrl-C kann der Server beendet werden (und das sollte man auch unbedingt vor dem Logout tun!).
Rahmenprogramm für Web-Anwendungen in
PLT-Scheme
Dieser Eintrag ist nur relevant, wenn du dich entschieden
hast die do-it-yourself-Methode zur
Servlet-Entwicklung zu benutzen!
Damit Servlets vom Webserver ausgeführt werden, müssen erst
entsprechende Bibliotheken eingebunden werden. Dies ist aber
relativ einfach und wird hier an einem Beispiel
demonstriert.
Servlets werden nur ausgeführt, wenn die Quelldateien in
einem bestimmten Pfad des Webservers liegen. Dies ist in
unserem Fall ~/plt-web/servlets. Wir wollen für dieses
Beispiel eine Datei say-hello.scm mit diesem
Inhalt in diesem Verzeichnis anlegen:
(require (lib "unitsig.ss")
(lib "servlet-sig.ss" "web-server")
(lib "servlet-helpers.ss" "web-server")
(lib "xml.ss" "xml"))
(unit/sig ()
(import servlet^)
;;; Servlet code
(define (say-hello)
`(html (head (title "Hallo!"))
(body ((bgcolor "white"))
(h2 "Hallo Welt!")
(p "Wie geht's denn so?"))))
(say-hello))
Dieses Programm als Textdatei
ECE Bid Pro: Ein- und
Ausgabeformat
Bid Pro erhält als Eingabe ein XML-Dokument, dass dieser DTD
entsprechen muss.
<!ELEMENT bids (bid)*> <!ELEMENT bid (auctionid, user, amount)> <!ELEMENT auctionid (#PCDATA)> <!ELEMENT user (#PCDATA)> <!ELEMENT amount (#PCDATA)>Diese DTD als Textdatei
<!ELEMENT bidproresults (winner)*> <!ELEMENT winner (auctionid, user, amount)> <!ELEMENT auctionid (#PCDATA)> <!ELEMENT user (#PCDATA)> <!ELEMENT amount (#PCDATA)>Diese DTD als Textdatei
<?xml version="1.0" ?> <!DOCTYPE bids SYSTEM "/afs/informatik.uni-tuebingen.de/pu/pfi-2002/share/bidpro-input.dtd">Die Benutzung von ECE Bid Pro ist denkbar einfach. ECE Bid Pro ist ein Programm für die Kommandozeile und wird mit einem Parameter gestartet: Dem Pfad zur Eingabedatei.
(require (lib "xml.ss" "xml"))
(define *ecebidpro-binary*
"/afs/wsi/pu/pfi-2002/i386_fbsd46/bin/ecebidpro")
(define (run-ecebidpro file-name)
(call-with-values
(lambda ()
(subprocess #f #f (current-output-port) *ecebidpro-binary* file-name))
(lambda (sp-value in out err)
(let ((xml (read-xml in)))
(subprocess-wait sp-value)
(let ((return-value (subprocess-status sp-value)))
(if (zero? return-value)
(xml->xexpr
((eliminate-whitespace '(bidproresults winner) (lambda (x) x))
(document-element xml)))
return-value))))))
Diese Programm als Textdatei
XML-Dokumente in PLT-Scheme (Dr. Scheme)
Eine ausführliche Beschreibung wie XML-Dokumente in Scheme
gelesen, geschrieben und repräsentiert sind, findet sich How
to use Scheme.
Den Prolog für XML-Dateien generieren
Aktualisiert am 27.1.2003
XML-Dokumente werden mit der Funktion write-xml
geschrieben (siehe unten). Diese Funktion erhält als erstes
Argument einen Record vom Typ document. Dieses
Record enthält den Prolog bestehend aus dem XML-Tag <?xml
version="1.0" ?> und dem DOCTYPE-Tag, sowie dem
Wurzelelement der XML-Datei. Möchte man eine XML-Datei
speichern, so muss zuerst ein entsprechendes
document-Record erzeugt werden:
(require (lib "xml.ss" "xml"))
(define (make-xml-document dtd-name dtd-filename xsl-href xexpr)
(make-document
(make-prolog
(if xsl-href
(list (make-pi #f #f 'xml "version=\"1.0\"")
(make-pi #f #f 'xml-stylesheet
(string-append "href=\"" xsl-href "\" type=\"text/xsl\"")))
(list (make-pi #f #f 'xml "version=\"1.0\"")))
(make-document-type dtd-name
(make-external-dtd/system dtd-filename)
#f))
(xexpr->xml xexpr)
'()))
;;; Beispiel 1: Ein XML-Dokument ohne xml-stylesheet
(display-xml
(make-xml-document
'liste "liste.dtd" #f
'(liste
(listenelement "Bla"))))
;;; Beispiel 2: Ein XML-Dokument mit xml-stylesheet
(display-xml
(make-xml-document
'liste "liste.dtd" "fancy-listendarstellung.xsl"
'(liste
(listenelement "Bla"))))
Dieses Programm als TextdateiXML-Dokumente einlesen und speichern
In diesem kleinen Beispiel wird die folgende XML-Datei
gelesen, um einen Eintrag erweitert und wieder
gespeichert. Dies ist die ursprüngliche XML-Datei:
<?xml version="1.0" ?>
<!DOCTYPE band SYSTEM "band.dtd">
<band>
<member>
<name>Ozzy Osbourne</name>
<instrument>vocals</instrument>
</member>
<member>
<name>Bill Ward</name>
<instrument>drums</instrument>
</member>
<member>
<name>Geezer Butler</name>
<instrument>bass</instrument>
</member>
</band>
Diese XML-Datei als Textdatei
(require (lib "xml.ss" "xml"))
(define (load-xml-file file-name)
(xml->xexpr
(document-element
(with-input-from-file file-name read-xml))))
(define (save-band-xml-file xexpr file-name)
(let ((port (open-output-file file-name)))
(write-xml
(make-xml-document 'band "band.dtd" #f xexpr) port)
(close-output-port port)))
(define (add-tony xexpr)
`(band
,@(append (cdr xexpr)
'((member
(name "Tony Iommi")
(instrument "guitar"))))))
(save-band-xml-file
(add-tony (load-xml-file "band.xml"))
"band-neu.xml")
Dieses Programm als Textdatei
<?xml version="1.0"?>
<!DOCTYPE band SYSTEM "band.dtd">
<band>
<member>
<name>Ozzy Osbourne</name>
<instrument>vocals</instrument>
</member>
<member>
<name>Bill Ward</name>
<instrument>drums</instrument>
</member>
<member>
<name>Geezer Butler</name>
<instrument>bass</instrument>
</member>
<member><name>Tony Iommi</name><instrument>guitar</instrument></member></band>
Diese XML-Datei als TextdateiEine Schnittstelle zur Bimasuun
Die Bimasuun erstellt automatisch eine Liste von
Angeboten. Da die Bimasuun mit den Ausmaßen 5,5x7,5x9 m und
dem Gewicht von 1,4 Tonnen ziemlich schwierig zu
transportieren ist, hat R. Winter einen Simulator zur
Verfügung gestellt. Dieser Simulator hat diesselbe
Schnittstelle, die auch die Bimasuun-Anbindungs-Bibliothek
bietet und kann hier
heruntergeladen werden.
Die Schnittstelle besteht aus der Funktion
bimasuun-get-offers, die keine Parameter hat. Der
Rückgabewert ist eine Liste von Angeboten. Ein Angebot ist
wiederrum eine Liste, die aus den folgenden Elementen
besteht:
(anfangspunkt endpunkt verbindungsart kapazitaet mindestgebot)anfangspunkt und endpunkt sind Strings, verbindungsart ist entweder das Symbol 'satellite oder 'groundlink. kapazitaet und mindestgebot sind Integerzahlen.
HTML-Frames
HTML-Frames sind eine Möglichkeit das Browserfenster
aufzuteilen, so dass mehrere HTML-Dokumente nebeneinander im
selben Fenster dargestellt werden. Ein sogenanntes
Frameset bestimmt dabei, wie die Aufteilung des
Browserfensters erfolgt. In den einzelnen Teilbereichen, den
Frames können nun HTML-Dokumente dargestellt
werden. Im Frameset wird ebenfalls festgelegt, welche
HTML-Dokument in welchem Frame dargestellt wird.
SelfHTML
enthält eine sehr gute Einführung in dieses Thema. Der offizielle
HTML-Standard enthält natürlich auch ein Kapitel über
Frames.
XSL-Stylesheets debuggen
Kommt es während der XSL-Transformationen zu einem Fehler,
so erhält der Benutzer keine Fehlermeldung -- für den
Entwickler ein echter Horror. Für die Entwicklung ist ein
XSL-Prozessor wünschenswert, der aussagekräftigere
Fehlermeldungen liefert. Dies leistet das Programm
xsltproc, das auf den FreeBSD-Rechner am WSI
installiert ist. Beispiel:
[knauel@duff xml-und-frames] xsltproc pfi-kommvv.xml xsltStylePreCompute: unknown xsl:for-eac xsltApplyOneTemplate: for-eac was not compiled
Scheme-Servlets geben JavaScript aus
Vielfach ist notwendig JavaScript-Code dynamisch zu
erzeugen, zum Beispiel um server-seitigt errechnete Werte in
das Programm einzufügen. JavaScripts können in X-Expressions
mit make-comment eingebettet werden. Hier ein
Beispiel:
(require (lib "xml.ss" "xml"))
(define *count* 10)
(define content
`(html
(head (title "Ein JavaScript-Versuch"))
(body
(script ((type "text/javascript"))
,(make-comment (string-append
"
count=" (number->string *count*) ";
for (var i = 1; i <= count; i++) {
document.write(\"i ist \" + i + \"
\");
}
document.write(\"Gehen Sie weiter, hier gibt es nichts zu sehen!\");
//")))
(br)
(p "Das war ein dynamisch erzeugtes JavaScript!"))))
(write-xml/content (xexpr->xml content))
Dieses Programm als Textdatei
Kommandozeilenprogramme mit
PLT-Scheme / Dr. Scheme
In PLT-Scheme / Dr. Scheme geschriebene Programme können
sehr leicht von der Kommandozeile aus ausgeführt werden. Der
Quelldatei wird nur ein entsprechender Aufruf des
Scheme-Interpreters für die Kommandozeile ("mzscheme")
vorangestellt:
#!/bin/sh ":";exec /afs/wsi/i386_fbsd46/bin/mzscheme -r "$0" "$@" (display "Hallo Welt!") (newline)Diese Datei wird mit chmod +x quelle ausführbar gemacht. Das Help-Desk von Dr.Scheme enthält im Kapitel "Running MzScheme" noch weitere Hinweise.
Entities in der Ausgabe einer
XSL-Transformation erzeugen
Gelegentlich ist es notwendig in der Ausgabe einer
XSL-Tranformation Entities zu erzeugen. Transformiert man
zum Beispiel ein XML-Dokument in ein HTML-Dokument, kann es
sinnvoll sein, das in der Ausgabe HTML-Entities erscheinen,
wie etwa (non-breaking space).
Diese Entities können auf diese Weise erzeugt werden:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xsl:stylesheet [
<!ENTITY test "<xsl:text disable-output-escaping='yes'> </xsl:text>">
]>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="html"/>
<xsl:template match="/">
<html>
<body bgcolor="#FFFFFF">
&test;
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Dies führt zur richtigen Ausgabe, doch leider wird das
Ergebnis u.a. im Mozilla nicht richtig dargestellt. Die
Entities in der Ausgabe der Transformation müssten eigentlich
gemäß den HTML-Regeln für Entities interpretiert und aufgelöst
werden, aber genau dieser Schritt passiert nicht. Deshalb
erscheint im Mozilla-Browserfenster an Stelle des
entsprechenden Zeichens der Text -- ein
Bug.
Dynamisch erzeugte XML-Dokumente mit
dem PLT-Webserver
Eingefügt am 27.1.2003; Aktualisiert am 28.1.2003
Der PLT-Webserver schickt dynamisch erzeugte Inhalte, also
Inhalte, die von einem Servlet erzeugt werden, mit dem
MIME-Typ text/html an den Browser. Soll ein
XML-Dokument dargestellt werden, muß allerdings ein
entsprechender MIME-Typ erst gesetzt werden. Die Prozedur
mime-type-text/xml nimmt als Parameter ein
X-Expression und gibt eine Liste zurück die Informationen
für den Web-Server enthält, so dass dieser den MIME-Typ
text/xml verwendet. Hier die Definition von
mime-type-text/xml und eine Beispielanwendung:
(require (lib "xml.ss" "xml"))
(define (mime-type-text/xml xexpr)
(cons "text/xml"
(list (xexpr->string xexpr))))
;;; Beispiel
(define my-xml-file
`(liste (element "1")
(element "2")
(element "3")))
(define (xml-document->string xml-document)
(let ((string-port (open-output-string)))
(write-xml xml-document string-port)
(get-output-string string-port)))
(define (mime-type-text/xml-document xml-document)
(cons "text/xml"
(list (xml-document->string xml-document))))
;;; Der Browser erhält ein Dokument vom Typ text/plain
;(send/finish my-xml-file)
;;; Der Browser erhält ein Dokument vom Typ text/xml
(send/finish
(mime-type-text/xml my-xml-file))
;;; Der Browser erhält ein Dokument vom Typ text/xml
(send/finish
(mime-type-text/xml-document
(make-xml-document 'liste "einfache-listen.dtd"
"wahnsinnig-huebsches-stylesheet.xsl"
my-xml-file)))
Dieses Programm als
Textdatei
PLT-Webserver: Richtiger MIME-Typ für
statische XML-Dokumente
Eingefügt am 27.1.2003
Einige Browser
(z. B. Mozilla) zeigen XML-Dokumente nur richtig an
(d. h. führen die XSL-Tranformationen durch), wenn der
Web-Server dieses Dokument mit dem MIME-Typ
text/xml ausliefert. Dieser
Artikel beschreibt, wie dies für dynamisch erzeugte
XML-Dokumente erreicht werden kann. Für statische
XML-Dokumente, also Dateien die nicht von einem Servlet
ausgegeben werden, ist die Sache aufgrund eines fehlendes
Features im PLT-Webserver etwas schwieriger. Die gute
Nachricht: Die am WSI installierte Version des PLT-Webserver
ist so modifiziert, das der richtige MIME-Typ gesendet wird
-- es ist also nichts zu tun. Die schlechte Nachricht
betrifft diejenigen, die den PLT-Webserver auf dem
heimischen Rechner laufen lassen. Hier muss die Datei
collects/web-server/web-server-unit.ss durch diese Version ausgetauscht
werden. Danach muß diese Datei noch entsprechend kompiliert
werden. Dazu muß einfach das Programm setup-plt
(unter Windows: "Setup PLT") aufgerufen werden.