Eine Webanwendung

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

In diesem Abschnitt entwickeln Sie eine Website, die mit dem XML-Switch und den anderen Systemen integriert ist, die in Ihrem Netzwerk laufen (selbst wenn Sie all das auf einen Rechner legen). In dieser Webanwendung navigieren Benutzer durch einiges HTML auf dem Server, das es ihnen ermöglicht, sich anzumelden (mit anderen Worten, ihr Profil abzurufen), ihre Profil-Informationen zu editieren oder spezielle Angebote zu sehen. Neben dem HTML läuft ein CGI-Skript, das von den HTML-Formularen und anderen Dingen aufgerufen wird, um die Informationen zu bekommen.

Eine Website oder ein CGI-Skript greift normalerweise direkt auf eine Datenbank zu, um für den Benutzer Informationen zu extrahieren. Diese Anwendung ist jedoch anders. In diesem Website-Beispiel benutzt das CGI-Skript den vorher erstellten xsc-Client, um direkt mit dem XML-Switch zu kommunizieren. Das heißt, anstelle von SQL-Abfragen sendet die Website XML-Nachrichten an den Switch. Der Switch bildet diese dann auf Objekte ab und ruft darauf die korrekte Methode auf, was letztlich bewirkt, daß die richtigen Informationen entweder eingefügt oder von dem XML-Switch zurückgegeben werden. Die zurückgegebenen Informationen werden dann geparst, in HTML formatiert und dem Benutzer angezeigt.

Verbinden mit einem Webdienst

Viele Webdienste können zu Beginn wie folgt implementiert werden. Bei den angekündigten Webdiensten von Microsoft (Codename HailStorm) sollte eine unabhängige Firma in der Lage sein, eine Website zu erstellen und den HailStorm-Kalender Ihres Benutzers abzurufen, indem SOAP-Aufrufe von Ihrem Webserver (oder dem Client) auf die Microsoft-Dienste durchgeführt werden. Das empfangene XML wird dann von Ihrer Website formatiert (sogar mit Ihrem Logo versehen) und an den Browser Ihres Benutzers zurückgegeben. Die hier vorgestellte Anwendung folgt demselben »Bridged-Services«-Szenario – abgesehen von einigen wichtigen Sicherheits- und Fehlerbehandlungsaspekten.

Die folgende Abbildung zeigt ein Diagramm, das sich auf die Website und ihre Beziehung zum XML-Switch und dem Rest des Netzwerks konzentriert.

Ein Detail der Webanwendung

Abbildung: Ein Detail der Webanwendung

Was diese Abbildung nicht zeigt und vielleicht auch nicht zeigen sollte, ist, daß der XML-Switch seinerseits mit anderen Netzwerkressourcen verbunden ist und effektiv als Blackbox für CGI und HTML arbeitet, die den Switch lediglich nach Daten fragen.

Die Komponenten

Die hier vorgestellte Web/CGI-Anwendung ist eine eigenständige Webanwendung. Sie ist komplett in das bisher aufgebaute XML-Switching-Netzwerk integriert. Diese Website verwendet eine HTML-Seite und ein Python-Skript auf dem Server, um dynamische Daten zu generieren. Das CGI-Skript benutzt den XML-Switch-Client, um Informationen von dem Switch und seinen Backend-Ressourcen zu gewinnen. Diese Website hat keinerlei Vorstellung davon, daß Profile in SQL Server und Angebote in einer großen flachen Datei gespeichert sind. Sie weiß nur, daß sie eine XML-Nachricht in einer gewissen Weise formatiert und daß das Übergeben der Nachrichten an den XML-Switch normalerweise dazu führt, daß die richtige Information zurückkommt.

Wir haben das HTML und die CGI-Skripten auf einen fünfzeiligen CGI-Server losgelassen, den wir in Python geschrieben haben. Da wir in diesem Buch durchgehend Apache und IIS benutzt haben, haben wir in diesem Abschnitt nach einer plattformübergreifenden Einfachheit gesucht und einen sehr einfachen CGIHTTPServer in Python benutzt. Die HTML-Seite intro.html und das CGI-Skript sp.py sollten auf jedem CGI-fähigen Webserver laufen.

In diesem Abschnitt entwickeln wir folgende Komponenten:

intro.html
Dies ist eine einfache Anmeldeseite, die eine Benutzer-ID akzeptiert und Sie an sp.py weiterleitet. Das Anmelde-Feld erwartet eine ID, die in der Datenbank gültig ist, die mit dem XML-Switch verbunden ist. Mit anderen Worten: Sie müssen dort eine gültige ID hinterlegen, die einem Datensatz entspricht, den Sie in Ihrer Datenbank in Erstellen der Datenbank vorher in diesem Kapitel erzeugt haben.

sp.py
Dies ist ein Python-CGI-Skript, das Informationen vom XML-Switch erhält und sie zur weiteren Anzeige formatiert. Sein Name endet nicht auf .cgi, obwohl Sie es so umbenennen sollten, falls Ihr CGI-Server nur .cgi-Dateien ausführt. Dieses Skript ist das Hauptarbeitspferd der Anwendung, da es nicht nur die Daten für Sie annimmt, sondern sie auch in HTML formatiert und dann an den Browser zurückschickt.

Wenn Sie diese fertigen Dateien in den Bereich Ihres Webservers legen, vergewissern Sie sich, sp.py in ein Verzeichnis namens cgi-bin unterhalb von intro.html zu legen. Das in intro.html benutzte Webformular und sp.py erwarten, die Datei sp.py als /cgi-bin/sp.py zu finden.

Zusätzlich sollten Sie xsc.py und XMLMessage.py) in das Verzeichnis cgi-bin kopieren, damit sp.py sie als Module laden kann.

Die Topologie

Wie zuvor in der Abbildung Ein Detail der Webanwendung gezeigt wurde, ist die CGI-Anwendung vorwiegend eine Folge von Transaktionen zwischen ihr selbst und einem Webbrowser. Wenn der Benutzer jedoch dynamische Informationen abfragt, benutzt das CGI-Skript den XML-Switch-Client, um mit dem XML-Switch über das Netzwerk zu kommunizieren. Dieses Beispiel hat weitreichende Auswirkungen für das Netzwerk: intro.html und sp.py werden von Ihrem Webserver angefragt; das Skript sp.py benutzt den XML-Switch-Client (xsc, erstellt im Beispiel xsc.py, der XML-Switch-Client), um sich erneut dorthin zu verbinden, wo immer Sie den XML-Switch-Server-Prozeß laufen lassen. Solange das CGI-Skript der Website dem Switch-Client sagt, wo der Switch-Server zu finden ist, bekommt er die Information, die er braucht. Natürlich muß der Browser eines Endbenutzers nur auf die Website verweisen.

In den folgenden paar Abschnitten heben wir einen Teil des mehr XML-zentrierten Codes hervor, der beim Bau dieser Site verwendet wird, und stellen komplette Listings der drei Hauptdateien vor.

Die Code-Architektur

Beim Erstellen jeder Website ist das allererste, was man tun kann, eine Startseite zu schreiben, in diesem Abschnitt intro.html. Die Datei intro.html ist eine einfache Seite, die höflich nach einer ID fragt. Benutzen Sie den Anmelden-Button, um Ihre ID an den Server zu schicken, und die Information wird vom CGI-Skript zurückgegeben und formatiert, das eine weitere, aber dynamisch erzeugte HTML-Seite erzeugt. Die folgende Abbildung zeigt intro.html in einem Webbrowser.

intro.html ist die Startseite für das CGI-Beispiel

Abbildung: intro.html ist die Startseite für das CGI-Beispiel

Wie die Abbildung zeigt, ist intro.html sehr einfach. Der wahrscheinlich schwierigste Teil ist, eine gültige ID aus Ihrer Profildatenbank zu holen. Das folgende Beispiel zeigt intro.html.

Beispiel: intro.html

<HTML>
  <HEAD>
    <TITLE>Einkauf-Portal von Super-Billig GmbH</TITLE>
  </HEAD>
  <BODY>
    <P align="center"><h1>Einkauf-Portal von Super-Billig GmbH</h1></P>
    <P>Hallo, wenn Sie noch nicht angemeldet sind, nehmen Sie sich bitte eine Minute daf&uuml;r Zeit. Diese Site ist personalisiert, und Ihre pers&ouml;nlichen Informationen werden zusammen mit Sonderangeboten dank unserer mit Python erstellten, XML verarbeitenden Infrastruktur angeboten. Diese Website verteilt kleine XML-Nachrichten an und von einem XML-Switch. Dieser Switch leitet die XML-Nachrichten an die richtige Stelle, schickt die Nachrichten an einen Handler und gibt dann das XML an diese Website zur&uuml;ck. Das XML kann Ihnen dann in Form von Profil-Informationen und Sonderangeboten angezeigt werden.</P>
    <P><h1>Willkommen</h1>
       <form name=login action="/cgi-bin/sp.py" method="GET">Bitte geben Sie eine g&uuml;ltige Kunden-ID an* <br><input type="text" size="15" name="id">&nbsp;<input type=submit value="Anmelden"><input type="hidden" name="mode" value="login"></form>
    </P>
    <P>*Diese ID mu&szlig; in Ihrer Profil-Datenbank existieren!</P>
  </BODY>
</HTML>

Es ist wichtig anzumerken, daß das Formular in diesem Beispiel eine versteckte Variable namens mode enthält, die auf login gesetzt ist. Diese wird als Hauptindikator für das CGI-Skript benutzt.

 <input type="hidden" name="mode" value="login"> 

Das CGI-Skript erkennt den Modus login und führt den entsprechenden Code aus.

Die Datei intro.html und ihr Stylesheet sind wertlos ohne einen Ort, wohin man sie senden kann. Das Anmelde-Feld nimmt nur eine ID entgegen, tut aber offensichtlich nichts. Das CGI-Skript hingegen nimmt die ID und legt damit los.

Die CGI-Funktionalität

Das CGI-Skript für diese Webanwendung ist sp.py, das später in diesem Kapitel im Beispiel sp.py gezeigt wird. Dieses Skript verfolgt vier Hauptzwecke. Der erste besteht darin, Ihre Kunden-ID zu nehmen und damit Ihre Profil-Informationen von irgendwo hinter dem XML-Switch zu gewinnen. Der zweite ist, Ihnen das Editieren Ihrer Profil-Informationen auf der gleichen Seite zu ermöglichen, auf der sie dargestellt sind. Der dritte Zweck ist, Ihr Aktualisierungsformular anzunehmen und die korrekte Nachricht an den Switch zurückzuschicken. Und der vierte ist, alle aktuellen Angebote im OfferXMLStore anzuzeigen. Bevor natürlich irgend etwas davon durchgeführt werden kann, muß das Skript erst seine Helferlein importieren. Wie zuvor erwähnt wurde, braucht das Skript Zugriff auf den XML-Switch-Client (xsc) und die XMLMessage-Klasse. Das Skript importiert auch einiges an XML-Standardfunktionalität:

import os
import cgi

from xsc import xsc
from XMLMessage import XMLMessage
from xml.dom.ext.reader.Sax2 import FromXml

Bevor der Server irgendeinen seiner vier Zwecke verfolgen kann, muß er auch einige Aufräumarbeiten durchführen, z. B. die richtigen Daten aus dem Abfrage-String extrahieren und feststellen, welche Methode er aufrufen muß:

# ''''''''''''''''''''''''''''''''''''''''''''
# HAUPTPROGRAMM
#
qs = cgi.parse_qs(os.environ["QUERY_STRING"])
mode = qs.get("mode", "")
id = qs.get("id", "")

print "Content-type: text/html"
print ""
print "<html>"
print """<HEAD><TITLE>Einkauf-Portal von Super-Billig GmbH (intro.html)</TITLE></HEAD><BODY>"""
print """<P align="center"><h1>Einkauf-Portal von Super-Billig GmbH</h1></P>"""
print """<p><h3>Klicken Sie <a href='/intro.html'>hier</a> zum Anmelden</h3>"""
print """ <h3>Klicken Sie <a href='/cgi-bin/sp.py?mode=getOffers'>hier</a> zum Sichten von Angeboten</h3></p>"""

if mode[0] == "updateProf":
doUpdateProfile()

if mode[0] == "login":
doLogin(id[0])

if mode[0] == "getOffers":
doGetOffers()

print "</body></html>"

Wie Sie sehen können, wird die meiste Arbeit von drei Methoden erledigt, doUpdateProf, doLogin und doGetOffers. Untersuchen wir diese im Detail, da sich darin die meisten XML-Aktionen abspielen.

Gewinnung von Profil-Informationen

Wenn Sie den Anmelden-Button drücken, sendet das Webformular in intro.html Ihre Benutzer-ID und den Modus an den Server. Wie vorher gezeigt wurde, ruft das Skript eine doLogin-Methode auf, sobald es den Anmeldemodus erkennt. Die login-Methode akzeptiert eine ID als Parameter und erzeugt die entsprechende getProfile-XML-Nachricht:

def doLogin(id):    
    """
    doLogin(id) - diese Methode schnappt sich ein Kundenprofil
    und zeigt es als XML im Browser an und stellt auch ein
    Formular bereit, das dem Benutzer erlaubt, seine eigenen
    Daten zu ändern.
    """
    # Fahre den XML-Switch-Client hoch
    xs = xsc()
    xs.server = "centauri:2112"
    # Bereite eine XML-Nachricht für den Server vor
    xmlmsg = XMLMessage()
    # Formatiere eine Nachricht für getProfile
    xmlmsg.setXMLMessage("""
    <message>
      <header><rpc/></header>
      <body>
        <object class="CustomerProfile" method="getProfile">
          <param>""" + id + """</param>
        </object>
      </body>
    </message>
                                        """)

Wie der vorige Code zeigt, ist das erste, was passiert, die Instanziierung des XML-Switch-Clients samt Zuweisung von centauri:2112 an die Variable xsc.server. Das bedeutet, wir betreiben den XML-Switch auf einem Rechner namens centauri auf dem Port 2112. Nach der Instanziierung des XML-Switch-Clients wird eine Nachricht vorbereitet, wie im vorherigen Code gezeigt. Da diese Nachricht die ID des aktuellen Benutzers enthält, zeigt der Server die korrekte Information an.

Es folgt das Absenden Ihrer getProfile-Anfrage mit Hilfe der xsc-Klasse, instanziiert als Objekt xs:

# Führe Aufruf im XML-Switch durch
xmlresp = xs.sendMessage(xmlmsg.getXMLMessage())

# Zeige die Antwort an
print "<P>Ihre empfangene Antwort:<br><xmp>"
print xmlresp
print "</xmp></p>"

# Setze Profil-XML-Nachricht auf und empfange DOM-Antwort
xmlmsg.setXMLMessage(xmlresp)
msgdom = xmlmsg.getXMLMessageDom()

Nachdem die doLogin-Methode Ihre Nachricht korrekt formatiert und mit einem Aufruf von xs.sendMessage an den Server geschickt hat, ist es Zeit, das Ergebnis zu parsen.

CustProfElement = msgdom.getElementsByTagName("CustomerProfile")[0]
CustProfElement.normalize()

# Picke ID-Nummer heraus
id = CustProfElement.getAttributeNS(None, "id")
print "<tr>"
print " <td colspan=2><b>Willkommen " + id + "</b></td>"
print "</tr>"   

# Iteriere über die Kinder, erzeuge dabei vor-ausgefülltes Formular...
nodes = CustProfElement.childNodes
for node in nodes:
   if node.nodeType == node.ELEMENT_NODE:
      print "<tr><td>"
      print "<b>" + node.nodeName + "</b>"
      print "</td><td>"
      for ec in node.childNodes:
         print "<input type=text size=20 name='" + node.nodeName + "' "
         print " value='" + ec.nodeValue + "'>"
      print "</td></tr>"

Zu diesem Zeitpunkt wird ein neues Formular erzeugt, mit dem Sie Felder in Ihrem Profil aktualisieren und ändern können. Die folgende Abbildung zeigt das vorausgefüllte Formular im Browser.

Das Formular zum Aktualisieren von Profil-Informationen

Abbildung: Das Formular zum Aktualisieren von Profil-Informationen

Wenn Sie auf Aktualisiere Profil klicken, würden Sie auf dem Server ein anderes Ereignis im Serverskript sp.py auslösen. Auch ändert sich dann Ihr Modus zu updateProf, und im XML-Switch wird ein anderer Aufruf durchgeführt. Ihre ID und Ihr Modus sind bereit und warten auf das nächste Formular mit versteckten Feldern in den Formularauszeichnungen:

print "<input type='submit' value='Aktualisiere Profil'>"
print "<input type='hidden' name='id' value='" + id + "'>"
print "<input type='hidden' name='mode' value='updateProf'>"

Obwohl die versteckten Eingabefelder nicht im Browser erscheinen, werden sie dennoch bei einer GET- oder POST-Operation mitgesendet.

Aktualisieren von Profil-Informationen

Wenn Sie Ihr Profil-Formular abschicken, wird das gleiche sp.py erneut aufgerufen, aber nun wurde Ihr Modus zu updateProf geändert. Wie Sie zuvor gesehen haben, wird abhängig vom Modus eine entsprechende Funktion aufgerufen. In diesem Fall ist es die Funktion doUpdateProfile.

Um die notwendige XML-Nachricht zu erzeugen, versucht das Skript als erstes, die Formularwerte aus dem Abfrage-String zu extrahieren und eine gültige XML-Nachricht zu erstellen:

xmlmsg = "<message><header><rpc/></header>\n"
xmlmsg += "<body><object class='CustomerProfile' method='updateProfile'>\n"
xmlmsg += "<param><CustomerProfile id="
xmlmsg += "'" + id[0] + "'>\n"
xmlmsg += "<firstname>" + qs.get("firstname","")[0].strip( ) + "</firstname>\n"
xmlmsg += "<lastname>" + qs.get("lastname","")[0].strip( ) + "</lastname>\n"
xmlmsg += "<address1>" + qs.get("address1","")[0].strip( ) + "</address1>\n"
xmlmsg += "<address2>" + qs.get("address2","")[0].strip( ) + "</address2>\n"
xmlmsg += "<city>" + qs.get("city","")[0].strip( ) + "</city>\n"
xmlmsg += "<state>" + qs.get("state","")[0].strip( ) +"</state>\n"
xmlmsg += "<zip>" + qs.get("zip","")[0].strip( ) +"</zip>\n"
xmlmsg += "</CustomerProfile></param></object></body></message>"
print xmlmsg
print "</xmp></p>"

In diesem Code wird jedes benötigte Feld einer updateProfile-XML-Anfrage mit Werten aus dem Webformular gefüllt, das gerade abgeschickt wurde. Mit der frisch erzeugten XML-Nachricht macht die Methode doUpdateProfile weiter, um die Nachricht tatsächlich an den XML-Switch weiterzuschicken:

xs = xsc()
xs.server = "centauri:2112"
resp = xs.sendMessage(xmlmsg)
print "<P>Empfangene Antwort:<br><xmp>"
print resp
print "</xmp></p>"

print "<h1>Erneut anmelden?</h1>"
print "<form name=login action='/cgi-bin/sp.py' method='GET'>"
print "Benutzen Sie Ihre aktuelle Kunden-ID:<br>"
print "<input type='text' size='15' name='id'"
print " value='" + id[0] + "'>&nbsp;"
print "<input type=submit value=' Anmelden '>"
print "<input type='hidden' name='mode' value='login'>"
print "</form>"

Zusätzlich zum Abschicken der Anfrage und der Anzeige einer Bestätigung erzeugt das Skript auch ein neues HTML-Formular, in dem Ihre ID bereits enthalten ist, so daß Sie wieder einloggen und Ihre modifizierte Information sehen können.

Anzeigen aller Angebote

Der Code für die Anzeige der Angebote ist nicht ganz einfaches XML, aber auch nicht das schwierigste, wenn Sie bisher gut mitgekommen sind. Zuerst muß eine XML-Nachricht vorbereitet werden, die das CGI-Skript an den XML-Switch senden wird:

xs = xsc( )
xs.server = "centauri:2112"

xmlmsg = str("""<message>             
                  <header><rpc/></header>
                  <body>
                    <object class="XMLOffer"
                      method="getAllOffers">
                    </object>
                  </body>
                </message>""")
resp = xs.sendMessage(xmlmsg)

Wie Sie sehen, wird die Nachricht sofort abgeschickt, nachdem sie vorbereitet wurde. Wenn alles geklappt hat, versucht die Methode doGetOffers, alle gültigen Angebote anzuzeigen:

offdom = FromXml(resp)
offers = offdom.getElementsByTagName("offer")

for offer in offers:
   offer.normalize( )
   for node in offer.childNodes:
     if (node.nodeType == node.ELEMENT_NODE):
       if (node.nodeName == "heading"):
      print "<h3>" + node.firstChild.nodeValue + "</h3>"
    if (node.nodeName == "description"):
      print "<p>" + node.firstChild.nodeValue + "</p>"

Hierbei verwenden Sie einige bekannte Methoden und Operationen von DOM. In diesem Fall wird ein Knoten nach seinen heading- und description-Knoten traversiert. Wenn sie gefunden werden, wird der Text darunter extrahiert.

Das komplette Listing von sp.py

Das folgende Beispiel zeigt das komplette Listing von sp.py.

Beispiel: sp.py

"""
sp.py - eine Folge von Webseiten und -formularen, die für den
Zugriff auf Daten Nachrichten an den XML-Switch schicken.
"""
import os
import cgi

from xsc import xsc
from XMLMessage import XMLMessage
from xml.dom.ext.reader.Sax2 import FromXml

def doLogin(id):      
   """
      doLogin(id) - diese Methode schnappt sich ein Kundenprofil und zeigt es als XML
      im Browser an und stellt auch ein Formular bereit, das dem Benutzer erlaubt,
      seine eigenen Daten zu ändern.
      """
      
      # Fahre den XML-Switch-Client hoch
      xs = xsc()
      xs.server = "centauri:2112"
      
      # Bereite eine XML-Nachricht für den Server vor
      xmlmsg = XMLMessage()

      # Formatiere eine Nachricht für getProfile
      xmlmsg.setXMLMessage("""
      <message>
      <header><rpc/></header>
      <body>
      <object class="CustomerProfile" method="getProfile">
      <param>""" + id + """</param>
      </object>
      </body>
      </message>
      """)
      # Zeige an, wie der XML-Switch per CGI angesprochen wird
      print "<p>In Ihrem Auftrag zu verschickende Nachricht:<br><xmp>"
      print xmlmsg.getXMLMessage()
      print "</xmp></p>"
      
      # Führe Aufruf im XML-Switch durch
      xmlresp = xs.sendMessage(xmlmsg.getXMLMessage())
      
      # Zeige die Antwort an
      print "<P>Ihre empfangene Antwort:<br><xmp>"
      print xmlresp
      print "</xmp></p>"
      
      # Setze Profil-XML-Nachricht auf und empfange DOM-Antwort
      xmlmsg.setXMLMessage(xmlresp)
      msgdom = xmlmsg.getXMLMessageDom()
      
      # Erzeuge ein Formular zum Editieren dieser neuen Profildaten
      print "<h1>Editieren Sie Ihr Profil</h1>"
      print "<form action='sp.py' method='GET'>"
      print "<table width=450 border=1>"
      
      # Parse Ergebnis
      try:
      CustProfElement = msgdom.getElementsByTagName("CustomerProfile")[0]
      CustProfElement.normalize()
      
      # Picke ID-Nummer heraus
      id = CustProfElement.getAttributeNS(None, "id")
      print "<tr>"
      print " <td colspan=2><b>Willkommen " + id + "</b></td>"
      print "</tr>"
      
      # Iteriere über die Kinder, erzeuge dabei vor-ausgefülltes Formular...
      nodes = CustProfElement.childNodes
      for node in nodes:
      if node.nodeType == node.ELEMENT_NODE:
      print "<tr><td>"
      print "<b>" + node.nodeName + "</b>"
      print "</td><td>"
      for ec in node.childNodes:
      print "<input type=text size=20 name='" + node.nodeName + "' "
      print " value='" + ec.nodeValue + "'>"
      print "</td></tr>"
      except:
      print "<tr><td>Ausnahmezustand</td><td>Gefunden</td></tr>"
      
      # Beende Formular
      print "<tr><td colspan=2>"
      print "<input type='submit' value='Aktualisiere Profil'>"
      print "<input type='hidden' name='id' value='" + id + "'>"
      print "<input type='hidden' name='mode' value='updateProf'>"
      print "</td></tr>"
      print "</table>"
      print "</form>"
      
   def doUpdateProfile():
      """
      doUpdateProfile() - diese Methode wird aufgerufen, um ein Profil
      mit einer updateProfile-XML-Nachricht zu aktualisieren.
      """
      print "<p>Ihre aktualisierte Nachricht:<br><xmp>"
      
      xmlmsg = "<message><header><rpc/></header>\n"
      xmlmsg += "<body><object class='CustomerProfile' method='updateProfile'>\n"
      xmlmsg += "<param><CustomerProfile id="
      xmlmsg += "'" + id[0] + "'>\n"
      xmlmsg += "<firstname>" + qs.get("firstname","")[0].strip() + "</firstname>\n"
      xmlmsg += "<lastname>" + qs.get("lastname","")[0].strip() + "</lastname>\n"
      xmlmsg += "<address1>" + qs.get("address1","")[0].strip() + "</address1>\n"
      xmlmsg += "<address2>" + qs.get("address2","")[0].strip() + "</address2>\n"
      xmlmsg += "<city>" + qs.get("city","")[0].strip() + "</city>\n"
      xmlmsg += "<state>" + qs.get("state","")[0].strip() + "</state>\n"
      xmlmsg += "<zip>" + qs.get("zip","")[0].strip() + "</zip>\n"
      xmlmsg += "</CustomerProfile></param></object></body></message>"
      print xmlmsg
      print "</xmp></p>"
      
      print "Aktualisierung wird vorgenommen..."
      
      xs = xsc()
      xs.server = "centauri:2112"
      resp = xs.sendMessage(xmlmsg)
      print "<P>Empfangene Antwort:<br><xmp>"
      print resp
      print "</xmp></p>"
      
      print "<h1>Erneut anmelden?</h1>"
      print "<form name=login action='/cgi-bin/sp.py' method='GET'>"
      print "Benutzen Sie Ihre aktuelle Kunden-ID:<br>"
      print "<input type='text' size='15' name='id'"
      print " value='" + id[0] + "'>&nbsp;"
      print "<input type=submit value=' Anmelden '>"
      print "<input type='hidden' name='mode' value='login'>"
      print "</form>"
      
   def doGetOffers():
      print "<p>Empfangen aller Angebote...</p>"
      xs = xsc()
      xs.server = "centauri:2112"
      xmlmsg = str("""<message>
      <header><rpc/></header>
      <body>
      <object class="XMLOffer" method="getAllOffers">
      </object>
      </body>
      </message>""")
      resp = xs.sendMessage(xmlmsg)
      
      print "<p>Formatieren der Serverantwort..."
      print "<h1>Angebote!</h1>"
      
      offdom = FromXml(resp)
      offers = offdom.getElementsByTagName("offer")
      
      for offer in offers:
      offer.normalize()
      for node in offer.childNodes:
      if (node.nodeType == node.ELEMENT_NODE):
      if (node.nodeName == "heading"):
      print "<h3>" + node.firstChild.nodeValue + "</h3>"
      if (node.nodeName == "description"):
      print "<p>" + node.firstChild.nodeValue + "</p>"
      # ''''''''''''''''''''''''''''''''''''''''''''
      # HAUPTPROGRAMM
      #
      qs = cgi.parse_qs(os.environ["QUERY_STRING"])
      mode = qs.get("mode", "")
      id = qs.get("id", "")
      print "Content-type: text/html"
      print ""
      print "<html>"
      print """<HEAD><TITLE>Einkauf-Portal von Super-Billig GmbH (intro.html)
      </TITLE></HEAD><BODY>"""
      print """<P align="center"><h1>Einkauf-Portal von Super-Billig GmbH</h1></P>"""
      print """<p><h3>Klicken Sie <a href='/intro.html'>hier</a> zum Anmelden</h3>"""
      print """ <h3>Klicken Sie <a href='/cgi-bin/sp.py?mode=getOffers'>hier</a>
      zum Sichten von Angeboten</h3></p>"""
      
      if mode[0] == "updateProf":
      doUpdateProfile()
      
      if mode[0] == "login":
      doLogin(id[0])
      
      if mode[0] == "getOffers":
      doGetOffers()
      
      print "</body></html>"            

Ausprobieren der Site als Benutzer

Wenn Sie einmal alle Vorbedingungen für diese Mammut-Website und die XML-Integration vollendet haben, werden Sie sehr wahrscheinlich alles mit einem Browser testen wollen. Dabei gibt es folgende acht Schritte, wie man vorgehen sollte:

  1. Vergewissern Sie sich, daß Ihr Webserver läuft und daß intro.html und sp.py korrekt funktionieren.
  2. Vergewissern Sie sich, daß Ihr XML-Switch läuft (runxs.py).
  3. Stellen Sie sicher, daß Ihre Webformulare auf Ihren Webserver zeigen und daß Ihre xsc-Aufrufe auf Ihren XML-Switch-Server zeigen.
  4. Rufen Sie intro.html im Browser auf, und geben Sie eine gültige ID aus Ihrer Datenbank in die Text-Box ein. Klicken Sie auf Anmelden.
  5. Sie können Ihr Profil sehen und es im Formular unten auf der Seite editieren.
  6. Wenn Sie Einträge geändert haben, klicken Sie im neuen Formular auf den Button Aktualisiere Profil, um sich erneut anzumelden.
  7. Prüfen Sie, ob sich Ihre Daten geändert haben, dann klicken Sie auf den Link, um Ihre Angebote zu sichten.
  8. Die Angebote sollten als formatiertes HTML angezeigt werden.

Die hier vorgestellte Web/CGI-Anwendung ist die Spitze des Integrationseisberges. Der Browser spricht mit der Website. Die Website spricht mit dem XML-Switch. Der XML-Switch benutzt lokale Objekte, um Informationen aus relationalen Datenbanken und Flatfile-Dateien zu bekommen. Durch die Standardisierung auf XML-Nachrichten zwischen verteilten Systemen und aufgrund einer vermittelnden Routing-Fähigkeit zwischen diesen Anwendungen werden ein wesentlich höherer Grad an Integration und weiterreichende Möglichkeiten hinsichtlich der Skalierung geboten.

  

zum Seitenanfang

<< 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