Im XLink-Kapitel haben wir Ihnen noch ein praktisches Beispiel versprochen, das wir jetzt nachholen werden. So schön die neuen Linking-Möglichkeiten auf dem Papier auch sind, sie sind eben genau das: nicht mehr als Text. Ohne Unterstützung der Browser kann man XLink/XPointer noch nicht verwenden. — Wenn da nicht Cocoon wäre und uns mit XSLT erlauben würde eine serverseitige Vorverarbeitung durchzuführen. Das Ziel des folgenden Beispiels ist folgendes: Ein XML-Dokument mit einem XLink soll in ein HTML-Dokument transformiert werden, das den Browser dazu bringt, sich genau so zu verhalten wie ein XLink-fähiger Browser. Dies wird dadurch möglich, dass man Browser in gewissem Maße programmieren kann, nämlich mit JavaScript. Wir beginnen mit dem Ausgangsdokument:
<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?> <?cocoon-process type="xslt"?> <?xml-stylesheet href="xlink.xslt" type="text/xsl"?> <html> <head> <title>Beispiel: Ein XLink-Feature mit JavaScript realisiert</title> </head> <body bgcolor="#ffffff" color="#000000"> <h1>Beispiel: Ein XLink-Feature mit JavaScript realisiert</h1> <p>Dies ist ein Beispiel für einen <erweitert type="extended" role="1-zu-n" > <locres role="quelle" type="resource"> <strong xnlns="http://www.w3.org/TR/REC-html40" >Erweiterten Link</strong> </locres> <remres role="ziel" type="locator" href="dokument1.html" title="Hier gehts zu Dokument 1"/> <remres role="ziel" type="locator" href="dokument2.html" title="Hier gehts zu Dokument 2"/> <arc type="arc" from="quelle" to="ziel" /> </erweitert>. Es handelt sich um einen multidirektionalen Inline-Link. Nach dem Anklicken der lokalen Resource (die markierte Textstelle) öffnet sich ein Auswahlfenster, das die alternativen Linkziele (entfernte Ressourcen) zeigt. Nach dem Anklicken eines Linkziels schließt sich das Auswahlfenster von selbst.</p> <p>Dieses Dokument ist ein <strong>XML-Dokument</strong>, das den Link gemäß XLink-Entwurf enthält. Es wird automatisch mit Hilfe eines <strong>XSLT-Stylesheets</strong> in HTML/JavaScript gewandelt.</p> <address>© 2000 Stefan Mintert, <a href="http://www.mintert.com/xml/">»XML in der Praxis«</a> </address></body> </html>
Was auf den ersten Blick nach HTML aussieht, ist es in Wirklichkeit nicht. Wir haben hier nur einige Elemente aus HTML übernommen. Zusätzlich ist dort aber auch ein Element namens erweitert zu finden. Dieses Element und seine Kindelemente sind XLink-Elemente des im Attribut type jeweils angegebenen Typs. Eigentlich sollte erweitert mit dem Attribut xmlns:xlink="http://www.w3.org/1999/xlink" versehen werden. Alle Attribute der Kindelemente sollten dann mit xlink: eingeleitet werden. Allerdings gab es noch Probleme mit der Namespace-Verarbeitung im XSLT-Stylesheet, so dass wir hier eine verkürzte Form zeigen. Die prinzipielle Vorgehensweise ändert sich dadurch nicht, auch wenn die Datei hier nicht standard-konform ist.
Wir haben dem Link die Rolle 1-zu-n
zugewiesen,
um anzuzeigen, dass hier von einer lokalen Ressource
(role="quelle") zu beliebig vielen entfernten
Ressourcen (role="ziel") verzweigt wird. Es liegt
hier also ein multidirektionaler Inline-Link vor. Bevor wir zur
Verarbeitung kommen, schauen wir uns zunächst das Verhalten im
Web-Browser an. In
Abbildung
73 ist der Text im
Navigator zu sehen. Die Location-Zeile verrät, dass hinter
der Seite XML steckt. Es ist zu erkennen, dass der Link in der für
HTML üblichen Weise hervorgehoben ist.
Nach dem Anklicken ( Abbildung 74) zeigt sich erst, dass der Link kein einfacher ist. Anstatt eine neue Webseite zu laden, öffnet sich ein kleines Auswahlfenster mit mehreren Zielen — ein multidirektionaler Link. Hier kann der Surfer nun sein gewünschtes Ziel (dokument1.html oder dokument2.html) anklicken; das kleine Fenster verschwindet und das neue Dokument erscheint im ursprünglichen Fenster.
Abbildung 74: Der erweiterte Link nach dem Anklicken: Ein Auswahlfenster zeigt alle Linkalternativen an
Dieses Verhalten ist eine von vielen Möglichkeiten zur Darstellung eine erweiterten Links. Schauen wir uns nun an, wie die technische Umsetzung aussieht. Das oben gezeigte XML-Dokument benutzt das Stylesheet xlink.xslt. Darin steckt die ganze Magie, wie dem Listing zu entnehmen ist:
<?xml version="1.0" encoding="ISO-8859-1"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- © 2000 Stefan Mintert --> <!-- ====================================================== --> <!-- Template fuer Root-Element 'html' --> <xsl:template match="html"> <xsl:processing-instruction name="cocoon-format">type="text/html"</xsl:processing-instruction> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- ====================================================== --> <!-- Template fuer Element 'head' --> <xsl:template match="head"> <head> <xsl:apply-templates select="@*|node()"/> <script language="javascript"> <![CDATA[ function pop_up_links() { self.name="mainwindow"; var win = window.open("","linkwindow","width=300,height=100,toolbar=0,status=0,scrollbars=1,titlebar=0,dependent=1"); win.document.open("text/html"); win.document.writeln("<HTML><HEAD><TITLE>Linkauswahl</TITLE></HEAD><BODY bgcolor='#000000' link='#ffffff' vlink='#ffffff'>"); for (var i = 0; i < arguments.length; i=i+2) win.document.writeln("<a target='mainwindow' onclick='setTimeout(\"self.close()\",500)' href='",arguments[i],"'>",arguments[i+1],"</a><br>"); win.document.writeln("<A href='javascript:self.close()'>Linkfenster schließen</A></BODY></HTML>"); win.document.close(); } ]]> </script> </head> </xsl:template> <!-- ====================================================== --> <!-- Default: Elemente kopieren --> <!-- Quelle: http://www.w3.org/TR/1999/REC-xslt-19991116#copying --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- ====================================================== --> <!-- Verarbeitung des erweiterten Links --> <xsl:template match='erweitert[attribute::type="extended"][attribute::role="1-zu-n"]'> <xsl:apply-templates select="locres"/> </xsl:template> <!-- Alle lokalen Quell-Ressourcen durchlaufen --> <xsl:template match='locres[attribute::type="resource"][attribute::role="quelle"]'> <a> <xsl:attribute name="href"> <xsl:text>javascript:pop_up_links(</xsl:text> <xsl:for-each select='parent::erweitert/child::remres[attribute::type="locator"][attribute::role="ziel"]'> <xsl:text>'</xsl:text> <xsl:value-of select="@href"/> <xsl:text>',</xsl:text> <xsl:text>'</xsl:text> <xsl:value-of select="@title"/> <xsl:text>'</xsl:text> <xsl:if test="not (position()=last())"> <xsl:text>,</xsl:text> </xsl:if> </xsl:for-each> <xsl:text>);</xsl:text> </xsl:attribute> <xsl:apply-templates /> </a> </xsl:template> </xsl:stylesheet>
Der erste Teil des Listings macht nicht viel: Die meisten Elemente werden unverändert übernommen. Einzig der Kopf wird um eine JavaScript-Funktion namens pop_up_links ergänzt. Das Skript steht in einer CDATA-Sektion, damit es keine Probleme mit darin enthaltenen spitzen Klammern und anderen Sonderzeichen gibt. Die Funktion öffnet das Linkauswahlfenster, wenn sie mit den richtigen Paramtern gefüttert wird. Das ist die Aufgabe des zweiten Teils, in dem der erweiterte Link verarbeitet wird. Wichtig ist hier das Template für locres zur Ausgabe des lokalen Linkbestandteils. In diesem Template wird ein HTML-Link zusammengebaut, der so aussieht:
Dies ist ein Beispiel für einen <a href="javascript:pop_up_links( \ 'dokument1.html','Hier gehts zu Dokument 1', \ 'dokument2.html','Hier gehts zu Dokument 2');"> <strong xnlns="http://www.w3.org/TR/REC-html40">Erweiterten Link</strong></a>.
Zur leichteren Lesbarkeit sind hier manuell Zeilenumbrüche eingefügt worden, die mit \ gekennzeichnet sind. Sie stehen natürlich nicht im HTML-Dokument.
Beim Anklicken des einfachen HTML-Links wird jetzt die Funktion mit den Parametern für Dokument 1 und 2 aufgerufen. Das Ergebnis haben Sie bereits oben gesehen.
Auch wenn wir uns in diesem Beispiel wegen praktischer Hindernisse nicht ganz an den Standard gehalten haben, so zeigt dieses Beispiel doch zweierlei: