Wenn man schon etwas unternimmt wie eine kleine
Literaturgeschichte, kommt man irgendwann auf die Idee, die
Daten, die zu einem bestimmten Tag im Jahr gehören, ausgeben
zu wollen. Wer hat am 1. Januar eines Jahres Geburtstag oder
ist an diesem Tag gestorben? Keiner (jedenfalls in der
vorliegenden Liste). Hier ist weniger das Sortieren gefragt,
obwohl man innerhalb der gefundenen Datensätze
sicherlich nach dem Geburtsjahr sortieren könnte. Wichtiger
ist, den Tag, um den es gehen soll, herauszufiltern. Und
natürlich die Frage, wie man über ein Stylesheet nicht nur
einen Tageskalendereintrag generiert, sondern gleich das
ganze Jahr im Überblick.
Zunächst zum konkreten Tag. Die Abfrage ist an sich einfach. Im Grunde ist nur das Template für die Autor(inn)en ein bisschen zu erweitern. Denn hier soll es ja nicht nur um Geburts-, sondern auch Todesdaten gehen.
<!-- ..................authors.............. --> <xsl:template match="author"> <xsl:if test="(vita/born/month = $thismonth and vita/born/day = $thisday) or (vita/died/day = $thisday and vita/died/month = $thismonth)"> <tr> <xsl:apply-templates select="name"/> <xsl:apply-templates select="vita/born | vita/died"/> </tr> </xsl:if> </xsl:template>
Im Vergleich zum Sortierbeispiel oben ist hier zum
and ein or hinzugekommen, das dafür
sorgt, nicht nur das Geburtsdatum zu überprüfen, sondern
auch das des Todesdatums. Das heißt, die Variablen
thismonth und thisday werden zweimal
abgefragt. Darüber hinaus steckt auch im zweiten der beiden
xsl:apply-templates ein oder
. Das
Stylesheet wählt vita/born und
vita/died aus. Dementsprechend ist außer für
vita/born noch ein Template für
viat/died vorhanden, das sich auch in einem
zusammenfassen ließe (weil Identisches ausgegeben
wird):
<xsl:template match="vita/born | vita/died"> ... </xsl:template>
Dieselben Variablen (thismonth und thisday) sind auch wichtig, wenn es darum geht, Dateien für einzelne Tage automatisch zu generieren: ein Kalendertag als Datei soll sich aus den beiden Variablen und der Endung .html zusammensetzen.
Wie das Beispiel der Softwareprodukte gezeigt hat,
bietet es sich zumindest beim Gebrauch bestimmter Programme
(hier Saxon) an, deren besondere
Eigenschaften auch zu nutzen, so problematisch das für die
Zukunft sein magNiemand weiß, ob
Michael Kay in der
Lage sein wird, seine Software auch weiterhin auf dem Stand
der Spezifikation (die sich ja ändern könnte) zu
halten..
Das folgende saxon:output-Statement generiert für einen bestimmten Tag eine HTML-Datei, wobei die Variablen thismonth und thisday sowohl global deklariert als auch auf der Kommandozeile oder per Programm gesetzt sein müssen.
<!-- ....................Root............... --> <xsl:template match="/lithist"> <saxon:output file="{$dir}{$filesep}{$thisday}.{$thismonth}.html" method="html" doctype-public="-//W3C//DTD HTML 4.0 Transitional" doctype-system="http://www.w3.org/TR/REC-html40" indent="yes"> ... </saxon:output>
Die beiden genannten Variablen sind insofern statisch, als sie etwa auf der Kommandozeile über
saxon lithistory.xml xsl/calendar.xsl \ thismonth=1 thisday=19 > html/01.19.html
gesetzt sein müssen. Will man aber nicht nur diese
eine Datei erzeugen, sondern das ganze Jahr abdecken, muss
ein Shell-Script oder Ähnliches her, das ein solches Stylesheet
reihenweise
aufruft. Geschwindigkeitsfanatikern sei
gesagt: das dauert. Immerhin: Es geht, und man kann sich den
Fortschritt in einer Shell stundenlang ansehen, wenn es
wirklich um das gesamte Jahr geht. Für den Batch-Betrieb ist
das aber bekanntlich kein Problem. Ein mögliches
nicht-optimiertes Shell-Script sieht so aus:
#!/bin/sh for i in 1 2 3 4 5 6 7 8 9 10 1 1 12 do for j in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 \ 18 19 20 21 22 23 24 25 26 27 28 29 30 31 do /usr/local/bin/saxon short-lh.xml xsl/calendar2.xsl \ thismonth=$i thisday=$j \ > html/$j.$i.html && echo " - $j/$i: done" done done echo "| file generated, now is the time for removing for i in html/30.2.html html/31.2.html html/31.4.html/31.6.html \ html/31.9.html html/31.11.html do rm $i && echo " - $i removed" done
Damit das Beispiel passt, sei hier als Tag (in deutscher Aussprache) der 13. April gewählt, weil mit Samuel Beckett und Seamus Heaney gleich zwei Autoren an diesem Tag Geburtstag haben. Der Screenshot zeigt es. Anschließend folgt das vollständige Listing.
Abbildung 37: XML-Literatur-Kalender für den 13. April: zwei Nobelpreisträger an demselben Tag geboren
<?xml version="1.0" encoding="ISO-8859-1"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/TR/REC-html40" xmlns:saxon="http://icl.com/saxon" saxon:trace="no" extension-element-prefixes="saxon"> <xsl:variable name="dir">html</xsl:variable> <xsl:variable name="filesep" select="system-property('file.separator')" /> <xsl:param name="thismonth"/> <xsl:param name="thisday"/> <!-- ....................Root............... --> <xsl:template match="/lithist"> <saxon:output file="{$dir}{$filesep}{$thisday}.{$thismonth}.html" method="html" doctype-public="-//W3C//DTD HTML 4.0 Transitional" doctype-system="http://www.w3.org/TR/REC-html40" indent="yes"> <html> <head> <meta name="author" content="Henning Behme" /> <title><xsl:apply-templates select="front/title"/></title> <style type="text/css"> body { background: #000000; color: #ccccff; font-family: sans-serif; } a:link { color: #ccccff; } a:visited { color: #ccffcc; } h3 { font-family: sans-serif; font-weight: bold; font-size: 18pt; text-align: center; color: #99ff99; } h5 { font-family: sans-serif; font-weight: bold; font-size: 14pt; text-align: center; color: #9999ff; } p { font-family: sans-serif; font-size: 10pt; text-align: left; color: #ffffff; } p.nocss { color: #000000; } .name { font-weight: bold; color: #99ff99; } .pseudonym { font-weight: bold; color: #669966; } .year { font-weight: bold; color: #9999ff; } .data { color: #ccccff; } .dom { font-family: sans-serif; font-weight: bold; font-size: 24; color: #99333; } </style> </head> <body> <table align="left" width="100%" border="0" cellspacing="0" cellpadding="0"> <tr><td width="15%" valign="top" rowspan="2"> <p><a href="/"><img src="/home/hb/images/io.jpg" border="0" alt="I/O"/></a></p> </td> <!-- rechte Tabellenteile --> <td> <p class="nocss">Ein Styleeshet-fähiger Browser würde sich gut machen ;-)<br/> A stylesheet-enabled browser would come in handy ;-)</p> <!-- Verarbeitung der weiteren Elemente --> <xsl:apply-templates select="front"/> <table border="1" cellpadding="4" cellspacing="0"> <caption><span class="dom">Tageskalender für den <xsl:value-of select="$thisday"/> <xsl:text>. </xsl:text> <xsl:value-of select="$thismonth"/> <xsl:text>. </xsl:text></span> </caption> <tr><th><span class="name">Autor(in) </span> <span class="pseudonym">[Pseudonym]</span></th> <th><span class="year">Geburtsjahr</span></th> <th><span class="data">Tag und Monat</span></th> <th><span class="year">Todesjahr</span></th> <th><span class="data">Tag und Monat</span></th> </tr> <xsl:apply-templates select="author"/> </table> <!-- ..............foot.................. --> <p>Last modification: March 10, 2000 by <a href="mailto:hb@behme.com">hb</a>.</p> </td></tr> </table> </body> </html> </saxon:output> </xsl:template> <!-- ...................front............... --> <xsl:template match="front"> <h3><xsl:apply-templates select="title"/></h3> <xsl:apply-templates select="theauthor"/> </xsl:template> <xsl:template match="title"> <xsl:value-of select="."/> </xsl:template> <xsl:template match="theauthor"> <h5><xsl:apply-templates/></h5> </xsl:template> <xsl:template match="name"> <xsl:apply-templates/> </xsl:template> <xsl:template match="fname"> <xsl:value-of select="."/> <xsl:text> </xsl:text> </xsl:template> <xsl:template match="lname"> <xsl:value-of select="."/> </xsl:template> <!-- ..................authors.............. --> <xsl:template match="author"> <xsl:if test="(vita/born/month = $thismonth and vita/born/day = $thisday) or (vita/died/day = $thisday and vita/died/month = $thismonth)"> <tr> <xsl:apply-templates select="name"/> <xsl:apply-templates select="vita/born | vita/died"/> </tr> </xsl:if> </xsl:template> <xsl:template match="author/name"> <td> <span class="name"><xsl:apply-templates/></span> </td> </xsl:template> <xsl:template match="vita/born"> <td align="center"> <span class="year"> <xsl:apply-templates select="year"/> </span> </td> <td align="center"> <span class="data"> <xsl:apply-templates select="day"/> <xsl:text>. </xsl:text> <xsl:apply-templates select="month"/> <xsl:text>. </xsl:text> </span> </td> </xsl:template> <xsl:template match="vita/died"> <td align="center"> <span class="year"> <xsl:apply-templates select="year"/> </span> </td> <td align="center"> <span class="data"> <xsl:apply-templates select="day"/> <xsl:text>. </xsl:text> <xsl:apply-templates select="month"/> <xsl:text>. </xsl:text> </span> </td> </xsl:template> <!-- ..................pseudonym.............. --> <xsl:template match="pseudonym"> <span class="pseudonym"> <xsl:text> [</xsl:text> <xsl:value-of select="."/> <xsl:text>]</xsl:text> </span> </xsl:template> <!-- .........diverse Elemente.............. --> <xsl:template match="fname|lname|year|month|day"> <xsl:value-of select="."/> </xsl:template> </xsl:stylesheet>