Websites aus XTM-Topic Maps generieren

(Auszug aus "XSLT Kochbuch" von Sal Mangano)

Problem

Sie möchten Wissen über einen Gegenstand in einer Topic Map festhalten, und zwar so, dass es leicht möglich ist, mit XSLT aus dieser Topic Map eine Website zu generieren.

Lösung

Die Lösung basiert auf einem Framework namens CTW (Cogitative Topic Maps Web Site), zu dem Sie eine Einführung in dem Buch XML Topic Maps finden, das von Jack Park herausgegeben wurde (Addison-Wesley, 2002). Diese Arbeit wurde erstmals auf der Konferenz Extreme Markup Languages 2000 vorgestellt.

Das CTW-Framework benutzt die folgende Abbildung von Topic Map-Elementen auf HTML:

Topic Map-Element HTML-Darstellung
Topic map Website
Topic Webseite
Topic associations Site Map
Topic occurrences Bilder, Grafiken, Text, HTML-Fragmente usw.
Topic names Seitenüberschriften, Titel, Listen und Hyperlink-Titel

Gegenstand der Topic Map, die wir erstellen, sind Algorithmen und insbesondere Sortier-Algorithmen. Das Wissen, das in dieser Topic Map dargestellt wird, wurde aus Informationsquellen aus dem Internet zusammengetragen und als Klasse-Unterklasse-Beziehungen zwischen Algorithmen sowie Belegstellen von Typbeschreibungen, Demonstrationen und Codebeispielen in mehreren Programmiersprachen strukturiert.

Nachdem der Gegenstand und der Inhalt der Website feststand, ergab sich die Ontologie der Subjekte und Objekte der Website auf ziemlich natürliche Weise. In CTW besteht die Ontologie-Schicht aus zwei Hauptbestandteilen: der Klassifikation von Topic-Gegenständen der Website und der Klassifikation von Topic-Merkmalen, die den Inhalt einer Webseite bilden.

Beide Klassifikationen spielen eine sehr wichtige Rolle bei der Gestaltung des Look-and-Feels einer Website. Die Art eines Topics bestimmt das Layout der Webseite, und die Art von Topic-Merkmalen beeinflusst den Stil von Elementen und Komponenten der Webseite. Das Ergebnis sehen Sie in der folgenden Abbildung.

Look-and-Feel einer generierten Website

Abbildung: Das Look-and-Feel einer generierten Website.

Die folgenden Unterabschnitte beschreiben die Gegenstände auf dieser Website über Sortier-Algorithmen.

Sortier-Algorithmen

Hauptgegenstände unserer Website sind die verschiedenen Unterklassen von Sortier-Algorithmen:

<topic id="sort">
  ...
</topic>
<association>
  <instanceOf>
    <topicRef xlink:href="#_class-subclass"/>
  </instanceOf>
  <member>
    <roleSpec>
      <topicRef xlink:href="#_superclass"/>
    </roleSpec>
    <topicRef xlink:href="#sort"/>
  </member>
  <member>
    <roleSpec>
      <topicRef xlink:href="#_subclass"/>
    </roleSpec>
    <topicRef xlink:href="#simplesort"/>
    <topicRef xlink:href="#in-place sort"/>
    <topicRef xlink:href="#heapsort"/>
    <topicRef xlink:href="#adaptivesort"/>
    <topicRef xlink:href="#distributionsort"/>
    <topicRef xlink:href="#mergesort"/>
  </member>
</association>

Anmerkung:
Die vollständige Version der Topic Map und der XSLT-Skripten ist online unter Cogito Ergo XML verfügbar. Dieser Abschnitt enthält nur einige Fragmente zur Illustration von Beispielanweisungen.

Jeder Sortier-Algorithmus kann seine eigenen Unterklassen haben. Zum Beispiel können Sie vier Varianten von in-place-sort aufzählen, die alle ihrerseits eigene Unterklassen haben könnten:

<association>
  <instanceOf>
    <topicRef xlink:href="#_class-subclass"/>
  </instanceOf>
  <member>
    <roleSpec>
      <topicRef xlink:href="#_superclass"/>
    </roleSpec>
    <topicRef xlink:href="#in-place sort"/>
  </member>
  <member>
    <roleSpec>
      <topicRef xlink:href="#_subclass"/>
    </roleSpec>
    <topicRef xlink:href="#quicksort"/>
    <topicRef xlink:href="#insertionsort"/>
    <topicRef xlink:href="#selsort"/>
    <topicRef xlink:href="#dimincrsort"/>
  </member>
</association>

Die für Standardisierungsfragen zuständige US-Behörde NIST (National Institute of Standards and Technology) unterhält eine hervorragende Website über Algorithmen und sammelt Informationen über verschiedenste Computer-Algorithmen. Jedem Algorithmus hat es eine eigene Webseite gewidmet. Diese Topic Map verwendet die URLs dieser Seiten als Adresse der Beschreibung des Aussagegegenstandes Algorithmus:

<topic id="insertionsort">
  <subjectIdentity>
    <subjectIndicatorRef xlink:href="http://www.nist.gov/dads/HTML/insertsrt.html"/>
  </subjectIdentity>

Neben ihrer Rolle in Klassen-Unterklassen-Beziehungen mit anderen Algorithmen verfügen Sortier-Algorithmen über weitere Topic-Merkmale wie Benennungen und Belegstellen.

In dieser Topic Map haben Sortier-Algorithmen Namen, mit denen man sie leicht identifizieren kann:

<baseName>
  <baseNameString>insertion sort</baseNameString>
</baseName>

Manchmal haben sie auch Alternativnamen, die als Benennungen im Gültigkeitsbereich also-known-as dargestellt werden:

<baseName>
  <scope>
    <topicRef xlink:href="#also-known-as"/>
  </scope>
  <baseNameString>linear insertion sort</baseNameString>
</baseName>

Die Beschreibung des Algorithmus ist als Topic-Belegstelle vom Typ description im Gültigkeitsbereich der Quelle der Beschreibung dargestellt. Der folgende Code ist ein Zitat von der NIST-Website (die deshalb im Gültigkeitsbereich des Topics nist angegeben ist), das man auch wie folgt lesen kann: »Im Kontext von NIST wird Sortieren durch Einfügen (engl. insertion-sort) beschrieben als ...«

<occurrence>
  <instanceOf>
    <topicRef xlink:href="#description"/>
  </instanceOf>
  <scope>
    <topicRef xlink:href="#nist"/>
  </scope>
  <resourceData>Sort by repeatedly taking the next item and inserting it into the final data structure in its proper order with respect to items already inserted.</resourceData>
</occurrence>

Links zu Algorithmus-Demonstrationen in Form von Applets und Animationen werden als Topic-Belegstellen des Typs demonstration dargestellt:

<occurrence>
  <instanceOf>
    <topicRef xlink:href="#demo"/>
  </instanceOf>
  <resourceRef xlink:href="http://www.cosc.canterbury.ac.nz/people/mukundan/dsal/ISort.html"/>
</occurrence>

Sie können auch Links auf die Implementierung von Sortier-Algorithmen erzeugen und in Ihrer Topic Map als Belegstellen des Typs code sample darstellen, die im Gültigkeitsbereich einer Programmiersprache definiert sind, in der die Algorithmen implementiert sind. Programmiersprachen sind eine weitere Klasse von Topics auf Ihrer Website, die eine orthogonale Dimension bei der Navigation darstellen:

  <occurrence>
    <instanceOf>
      <topicRef xlink:href="#code"/>
    </instanceOf>
    <scope>
      <topicRef xlink:href="#fortran"/>
    </scope>
    <resourceRef xlink:href="http://gams.nist.gov/serve.cgi/Module/TOMS/505/8547"/>
  </occurrence>
  <occurrence>
    <instanceOf>
      <topicRef xlink:href="#code"/>
    </instanceOf>
    <scope>
      <topicRef xlink:href="#java"/>
    </scope>
    <resourceRef xlink:href="http://www.cs.ubc.ca/spider/harrison/Java/InsertionSortAlgorithm.java"/>
  </occurrence>
</topic>

Das ist die gesamte Information, die wir über Algorithmen darstellen wollten. Dafür werden Sie Folgendes erstellen: Seitenüberschriften, Links auf verwandte Algorithmen, Beschreibungen und Links auf Seiten im Web mit Erklärungen zum Algorithmus, Links auf Demonstrationen und Code-Beispiele mit weiteren Links auf Programmiersprachen, in denen diese Beispiele implementiert sind.

Programmiersprachen

Hier zählt nur, dass Programmiersprachen mit ihren jeweiligen Namen und Definitionen aus Instanzen der Klasse programming language bestehen:

<topic id="java">
  <subjectIdentity>
    <subjectIndicatorRef xlink:href="http://foldoc.doc.ic.ac.uk/foldoc/foldoc.cgi?query=java"/>
  </subjectIdentity>
  <instanceOf>
    <topicRef xlink:href="#plang"/>
  </instanceOf>
  <baseName>
    <baseNameString>Java</baseNameString>
  </baseName>
  <occurrence>
    <instanceOf>
      <topicRef xlink:href="#definition"/>
    </instanceOf>
    <scope>
      <topicRef xlink:href="#cnet"/>
    </scope>
    <resourceData>Sun Microsystems' Java is a programming language for adding animation and other action to Web sites. The small applications (called applets) that Java creates can play back on any graphical system that's Web-ready, but your Web browser has to be Java-capable for you to see it. According to Sun's description, Java is a "simple, object-oriented, distributed, interpreted, robust, secure, architecture-neutral, portable, high-performance, multithreaded, dynamic, buzzword-compliant, general-purpose programming language." </resourceData>
  </occurrence>
</topic>

Die Programmiersprachen-Seite, die in der folgenden Abbildung zu sehen ist, umfasst Verweise auf Code-Beispiele, die in dieser Sprache implementiert sind, sowie Querverweise auf die implementierten Algorithmen.

Programmiersprachen-Seite

Abbildung: Programmiersprachen-Seite.

Wurzel-Topic

Im CTW-Framework ist root das Wurzel-Topic, dessen Aussagegegenstand vom Topic Map-Dokument selbst beschrieben wird. In der Terminologie von Topic Maps »vergegenständlicht« das Wurzel-Topic das Topic Map-Dokument, zu dem es gehört:

<topic id="default">
  <subjectIdentity>
    <subjectIndicatorRef xlink:href="#map"/>
  </subjectIdentity>

Bei der Vereinigung von Topic Maps in CTW wird dieses Topic zu den Gültigkeitsbereichen aller Zuweisungen von Topic-Merkmalen hinzugefügt. Noch wichtiger ist, dass dieses Topic der Startseite der CTW-Website entspricht.

In diesem Beispiel wird dessen Hyperlink-Name in der oberen linken Ecke auf allen Seiten Ihrer Website angezeigt:

<baseName>
  <baseNameString>Sort algorithms home</baseNameString>
</baseName>

An dieser Stelle sollten Anmerkungen zur und Behauptungen über die Topic Map gespeichert werden. Dieses Beispiel beschränkt sich auf die Beschreibung von Projekt- und Copyright-Metadaten:

  <occurrence>
    <instanceOf>
      <topicRef xlink:href="#definition"/>
    </instanceOf>
    <resourceData><![CDATA[This web site covers the subject of algorithms and specifically sorting algorithms.<br><br> It was created for the purposes of a CTW recipe for the O'Reilly XSLT Cookbook.]]> </resourceData>
  </occurrence>
</topic>

Die in der folgenden Abbildung dargestellte Wurzelseite zeigt als Einführung zur Website nur die Projektbeschreibung.

Wurzelseite der Sortier-Algorithmen-Website

Abbildung: Wurzelseite der Sortier-Algorithmen-Website.

Seitenelemente und Layout

Zuerst definieren Sie die Variable root, die das Wurzel-Topic darstellt: Wie weiter oben erwähnt wurde, wird dieses Topic vom umgebenden Topic Map-Dokument beschrieben:

<xsl:variable name="root" select="//topic[subjectIdentity/subjectIndicatorRef/@xlink:href = concat('#',/topicMap/@id)]"/>

Den gleichen Knoten könnten Sie mit Hilfe des subjectIndicator-Schlüssels erhalten, der mit Topics übereinstimmt, deren Ressourcenadresse passt:

<xsl:key name="subjectIndicator" match="topic" use="subjectIdentity/subjectIndicatorRef/@xlink:href"/>
<xsl:variable name="root" select="key('subjectIndicator',concat('#',/topicMap/@id))"/>

Zuerst generieren Sie die Standardseite, indem Sie das Layout-Template root-page für das Wurzel-Topic aufrufen:

<xsl:template match="/">
  <xsl:call-template name="root-page">
    <xsl:with-param name="this" select="$root"/>
  </xsl:call-template>

Als Nächstes generiert der Code Webseiten für alle Unterklassen von sorting algorithm. Hierbei rufen Sie das Layout-Template algorithm-page mit einem einfachen sorting algorithm als this-Parameter auf. Das Template ruft sich rekursiv selbst auf, um über alle Unterklassen zu iterieren:

<xsl:call-template name="algorithm-page">
  <xsl:with-param name="this" select="key('topicByID','#sort')"/>
</xsl:call-template>

Das Stylesheet generiert für alle Instanzen einer Programmiersprache jeweils eine Seite, indem es das Layout-Template plang-page aufruft:

  <xsl:for-each select="key('instanceOf','#plang')">
    <xsl:call-template name="plang-page"/>
  </xsl:for-each>
</xsl:template>

Der instanceOf-Schlüssel gibt die Topic-Instanzen aller Klassen basierend auf den gehashten IDs der Klassen-Topics zurück:

<xsl:key name="instanceOf" match="topic" use="instanceOf/topicRef/@xlink:href" />

Wie Sie in den Screenshots vielleicht schon bemerkt haben, verfügen alle drei Layout-Templates über die gleiche Unterteilung in vier rechteckige Bereiche. Gesteuert wird das von dem gemeinsamen Template, das die Startseite erzeugt. Zuerst weisen Sie den Prozessor an, eine Ausgabedatei relativ zum Ausgabeordner zu erzeugen, der im Parameter $out-dir angegeben ist, und den Title-Header aus der Benennung des aktuellen Topics im unbeschränkten Gültigkeitsbereich zu erzeugen. Letzteres wird erreicht, indem die mit dem Template übereinstimmenden topic-Elemente im label-Modus instanziiert werden. Dann beginnen Sie die Unterteilung der Seite in vier Bereiche. In der linken oberen Ecke erzeugen Sie einen Hyperlink auf die Startseite, dessen Bezeichnung der Name des root-Topics im unbeschränkten Gültigkeitsbereich ist. Diese Aufgabe erledigt das mit dem Topic übereinstimmende Template im link-Modus. Im rechten oberen Teil der Seite werden Sie eine Auswahl von Links auf Seiten zu Programmiersprachen haben. Diese wird mit Hilfe einer Iteration über alle Instanzen von Programmiersprachen-Topics erzeugt. In der linken unteren Ecke der Seite (unter dem Link auf die Startseite) geben Sie den Teil der Sitemap aus, der der Klassifikation der Sortier-Algorithmen entspricht. Und im Hauptteil rechts unten auf der Seite geben Sie den Hauptinhalt aus, der dem aktuellen Topic entspricht, der im content-Parameter an das page-Template übergeben wurde:

<xsl:template name="page">
  <xsl:param name="this"/>
  <xsl:param name="content"/>
  <redirect:write select="concat($out-dir,$this/@id,'.html')">
    <HTML>
      <head>
        <title>
          <xsl:apply-templates select="$this" mode="label"/>
        </title>
      </head>
      <body>
        <table width="1000" height="100%" cellspacing="0" cellpadding="10">
          <tr>
            <td width="250" height="20" bgcolor="#ffddbb" align="center">
              <xsl:apply-templates select="$root" mode="link"/>
            </td>
            <td width="750" height="20" valign="top" bgcolor="#eeeeee">
              <table cellspacing="10">
                <tr>
                  <xsl:for-each select="key('instanceOf','#plang')">
                    <td background="grey">
                      <xsl:apply-templates select="." mode="link"/>
                    </td>
                  </xsl:for-each>
                </tr>
              </table>
            </td>
          </tr>
          <tr>
            <td valign="top" bgcolor="#eeeeee">
              <xsl:call-template name="sitemap">
                <xsl:with-param name="classRef">#sort</xsl:with-param>
                <xsl:with-param name="current" select="$this/@id"/>
              </xsl:call-template>
            </td>
            <td valign="top" bgcolor="#ffeedd" >
              <xsl:copy-of select="$content"/>
            </td>
          </tr>
        </table>
      </body>
    </HTML>
  </redirect:write>
</xsl:template>

Das vorherige Template benutzt das mit baseName übereinstimmende Template im label-Modus:

<xsl:template match="topic" mode="label">
  <xsl:value-of select="baseName[not(scope)]/baseNameString"/>
</xsl:template>

Das mit baseName übereinstimmende Template im link-Modus erzeugt einen Hyperlink auf die Webseite des Topics:

<xsl:template match="topic" mode="link">
  <a href="{@id}.html">
    <xsl:value-of select="baseName[not(scope)]/baseNameString"/>
  </a>
</xsl:template>

Später im Code werden Sie das auf baseName passende Template im subject-indicator-Modus benutzen. Dieses Template erzeugt einen Hyperlink auf eine Ressource, die das passende Topic beschreibt:

<xsl:template match="topic" mode="indicator">
  <a href="{subjectIdentity/subjectIndicatorRef/@xlink:href}">
    <xsl:value-of select="baseName[not(scope)]/baseNameString"/>
  </a>
</xsl:template>

Das sitemap-Template iteriert über alle Unterklassen des sort-Topics, erzeugt Hyperlinks auf Seiten, die den abgeleiteten Algorithmen entsprechen, und ruft sich rekursiv selbst auf, um über Unterklassen von Unterklassen zu iterieren:

<xsl:template name="sitemap">
  <xsl:param name="classRef"/>
  <xsl:param name="current"/>
  <xsl:variable name="topic" select="key('topicByID',$classRef)"/>
  <xsl:choose>
    <xsl:when test="$topic/@id=$current">
      <span class="A">
       <xsl:apply-templates select="$topic" mode="label"/>
      </span>
    </xsl:when>
    <xsl:otherwise>
      <xsl:apply-templates select="$topic" mode="link"/>
    </xsl:otherwise>
  </xsl:choose>
  <xsl:variable name="aref" select="key('classAssoc',$classRef)"/>
  <xsl:if test="$aref">
    <ul>
      <xsl:for-each select="$aref/member[roleSpec/topicRef/@xlink:href='#_subclass']/topicRef">
        <li>
          <xsl:call-template name="sitemap">
            <xsl:with-param name="classRef" select="@xlink:href"/>
            <xsl:with-param name="current" select="$current"/>
          </xsl:call-template>
        </li>
      </xsl:for-each>
    </ul>
  </xsl:if>
</xsl:template>

Der classRef-Schlüssel, der vom sitemap-Template benutzt wird, verwendet die ID eines angegebenen Topics, um passende superclass-subclass-Beziehungen zu finden, in denen das Topic die Rolle super-class spielt:

<xsl:key name="classAssoc" match="association[instanceOf/topicRef/@xlink:href='#_class-subclass']" use="member[roleSpec/topicRef/@xlink:href='#_superclass']/topicRef/@xlink:href" />

Später im Code werden Sie einen subClassRef-Schlüssel benutzen, der auch auf superclass-subclass-Beziehungen passt, dann aber member benutzt, wobei das Topic die Rolle sub-class spielt:

<xsl:key name="subClassAssoc" match="association[instanceOf/topicRef/@xlink:href='#_class-subclass']" use="member[roleSpec/topicRef/@xlink:href='#_subclass']/topicRef/@xlink:href" />

Nun sind Sie so weit, dass Sie mit den drei Layout-Templates weitermachen können.

Das Layout-Template root-page ist sehr einfach. Rufen Sie das zuvor beschriebene Seiten-Template auf, und übergeben Sie ihm im content-Parameter den generierten HTML-Code für Belegstellen vom Typ description:

<xsl:template name="root-page">
  <xsl:param name="this"/>
  <xsl:call-template name="page">
    <xsl:with-param name="this" select="$this"/>
    <xsl:with-param name="content">
      <font size="+1">
        <xsl:apply-templates select="$this/occurrence[instanceOf/topicRef/@xlink:href='#description']"/>
      </font>
    </xsl:with-param>
  </xsl:call-template>
</xsl:template>

Das Layout-Template plang-page ist ein wenig komplizierter. Sein Titel setzt sich zusammen aus dem Namen des aktuellen Topics, gefolgt vom Namen des Topic-Typs. Dann verweist eine Zeile mit der Adresse auf eine Beschreibung des Aussagegegenstands auf eine andere Stelle im Web, an der der Gegenstand des Topics definiert wird. Danach folgen Topic-Beschreibungen, sofern vorhanden. Sie iterieren über alle in der aktuellen Sprache implementierten Code-Belegstellen und geben einen Link dazu aus. In eckigen Klammern hinter der Ressource setzen Sie einen Link auf den Sortier-Algorithmus, der in dieser Ressource implementiert wird:

<xsl:template name="plang-page">
  <xsl:param name="this" select="."/>
  <xsl:call-template name="page">
    <xsl:with-param name="this" select="$this"/>
    <xsl:with-param name="content">
      <font size="+2">
        <xsl:apply-templates select="$this" mode="label"/>, a
        <xsl:apply-templates mode="label" select="key('topicByID',$this/instanceOf/topicRef/@xlink:href)" />.
      </font>
      <br/><br/>
      <xsl:apply-templates select="$this/subjectIdentity"/>
      <xsl:apply-templates select="$this/occurrence[instanceOf/topicRef/@xlink:href='#description']"/>
      <xsl:variable name="codes" select="key('plang-codes',concat('#',$this/@id))"/>
      <xsl:if test="$codes">
        <span>Sorting algorithms implemented in <xsl:apply-templates select="$this" mode="label"/>:</span>
        <ul>
          <xsl:for-each select="$codes">
            <li>
              <a href="{resourceRef/@xlink:href}">
                <xsl:value-of select="resourceRef/@xlink:href"/>
              </a> [<xsl:apply-templates select=".." mode="link"/>]<br/>
            </li>
          </xsl:for-each>
        </ul>
        <br/><br/>
      </xsl:if>
    </xsl:with-param>
  </xsl:call-template>
</xsl:template>

Der weiter oben benutzte plang-codes-Schlüssel passt auf alle Belegstellen in der Topic Map, egal, welche Themen sie als Gültigkeitsbereich haben:

<xsl:key name="plang-codes" match="occurrence" use="scope/topicRef/@xlink:href"/>

Als Letztes folgt das Layout-Template algorithm-page. Dessen Titel setzt sich aus dem Namen des aktuellen Topics, gefolgt von also-known-as-Namen in eckigen Klammern zusammen. Und nach der Adresszeile des Aussagegegenstands folgt die Liste der Oberklassen, sofern vorhanden, von denen der aktuelle Sortier-Algorithmus abgeleitet ist. Dann finden Sie eine oder mehrere Beschreibungen von Sortier-Algorithmen, gefolgt von einer Liste von Links auf Belegstellen, die Demonstrationen zum Algorithmus bieten und der Liste von Codebeispielen mit Querverweisen auf Implementierungen in verschiednene Programmiersprachen, die in eckigen Klammern stehen. Am Ende der Seite listen Sie Unterklassen oder Varianten des aktuellen Sortier-Algorithmus auf, sofern vorhanden. Und schließlich ruft sich das Layout-Template algorithm-page rekursiv selbst auf, um Seiten für Unterklassen von all seinen Unterklassen auszugeben:

<xsl:template name="algorithm-page">
  <xsl:param name="this"/>
  <xsl:call-template name="page">
    <xsl:with-param name="this" select="$this"/>
    <xsl:with-param name="content">
      <font size="+2">
        <xsl:apply-templates select="$this" mode="label"/>
        <xsl:if test="$this/baseName[scope/topicRef/@xlink:href='#also-known-as']">[<xsl:value-of select="$this/baseName[scope/topicRef/@xlink:href='#also-known-as']/baseNameString"/>]</xsl:if>
      </font>
      <br/><br/>
      <xsl:apply-templates select="$this/subjectIdentity"/>
      <xsl:variable name="superclasses" select="key('subClassAssoc',concat('#',$this/@id))member[roleSpec/topicRef/@xlink:href='#_superclass']/topicRef"/>
      <xsl:if test="$superclasses">Inherits from
        <xsl:for-each select="$superclasses">
          <xsl:apply-templates select="key('topicByID',@xlink:href)" mode="link"/>
            <xsl:if test="position( ) != last( )">, </xsl:if>
        </xsl:for-each>
        <br/><br/>
      </xsl:if>
      <xsl:apply-templates select="$this/occurrence[instanceOf/topicRef/@xlink:href='#description']"/>
      <xsl:variable name="demos" select="$this/occurrence[instanceOf/topicRef/@xlink:href='#demo']"/>
      <xsl:if test="$demos">
        <span>Demonstrations: </span>
        <ul>
          <xsl:for-each select="$demos">
            <li>
              <a href="{resourceRef/@xlink:href}"><xsl:value-of select="resourceRef/@xlink:href"/></a>
              <br/>
            </li>
          </xsl:for-each>
        </ul>
        <br/>
      </xsl:if>
      <xsl:variable name="codes" select="$this/occurrence[instanceOf/topicRef/@xlink:href='#code']"/>
      <xsl:if test="$codes">
        <span>Implementations and sample code: </span>
        <ul>
          <xsl:for-each select="$codes">
            <li>
              <a href="{resourceRef/@xlink:href}">
                <xsl:value-of select="resourceRef/@xlink:href"/>
              </a>[<xsl:apply-templates mode="link" select="key('topicByID',scope/topicRef/@xlink:href)"/>]
            </li>
          </xsl:for-each>
        </ul>
        <br/>
      </xsl:if>
      <xsl:variable name="subclasses" select="key('classAssoc',concat('#',$this/@id))/member[roleSpec/topicRef/@xlink:href='#_subclass']/topicRef"/>
      <xsl:if test="$subclasses">
        See also
        <xsl:value-of select="$this/baseName[not(scope)]/baseNameString"/>
        variants:
        <xsl:for-each select="$subclasses">
          <xsl:apply-templates select="key('topicByID',@xlink:href)" mode="link"/>
          <xsl:if test="position( ) != last( )">, </xsl:if>
        </xsl:for-each>
      </xsl:if>
    </xsl:with-param>
  </xsl:call-template>
  <xsl:variable name="aref" select="key('classAssoc',concat('#',$this/@id))"/>
  <xsl:for-each select="$aref/member[roleSpec/topicRef/@xlink:href='#_subclass']/topicRef">
    <xsl:call-template name="algorithm-page">
      <xsl:with-param name="this" select="key('topicByID',@xlink:href)"/>
    </xsl:call-template>
  </xsl:for-each>
</xsl:template>

Diskussion

Topic Maps sind eine Technologie, mit der Wissen über Bereiche der realen Welt gesammelt und verwaltet wird. In diesem Fall haben Sie Beziehungen zwischen Algorithmen und anderen Objekten und Ressourcen dargestellt. Wenn Sie vorsichtig sind und die Konventionen von CTW befolgen, können Sie aus einer Topic Map als Quelle eine ganze Website generieren.

In der hier gezeigten Lösung waren Sie auf nur wenige Typen von Objekten und Beziehungen dazwischen beschränkt. Anwendungen aus dem realen Leben sind wesentlich komplexer. Hier bestand mein Hauptanliegen vor allem darin, die Mächtigkeit und vielfältigen Möglichkeiten zu demonstrieren, die das CTW-Framework bietet.

Im CTW-Framework steuert ein einziges Topic Map-Dokument sowohl den Inhalt als auch die Struktur einer gesamten Website. Eine saubere CTW-Topic-Map-Architektur ermöglicht die robuste und intuitive Wartung von Links zwischen Webseiten, deren Inhalt und den dazugehörigen Metadaten. Websites, die mit CTW erstellt wurden, können leicht miteinander vereint werden und sind immun gegen Links auf nicht vorhandene Seiten. XSLT bietet ein konsistentes Look-and-Feel, Plattformunabhängigkeit und Wiederverwendbarkeit.

Aber Sie müssen auch einen Preis zahlen, um in den Genuss all dieser Vorteile zu kommen: Das CTW-Framework verlangt, dass Sie Begriffe wie Topics, Topic-Merkmale und Beziehungen verwenden, wenn Sie an Ihre Inhalte denken. Bei diesem Ansatz sind Sie darauf beschränkt, Inhalte zu erzeugen, die in den Rahmen der gewählten Ontologie hineinpassen, aber er hilft dabei, das auf der Website dargestellte Wissen gut organisiert und navigierbar zu halten.

XSLT unterstützt CTW insofern, weil es eine modulare und wartbare Möglichkeit bietet, das Wissen in der Topic Map zu transformieren und Stile darauf anzuwenden. Dynamische CTW-basierte Lösungen, die mit XSLT erzeugt wurden, skalieren bis zu mehreren Tausend Topics, und statische Lösungen werden nur durch den vorhandenen Platz auf der Festplatte beschränkt.

Siehe auch

XML Topic Maps: Creating and Using Topic Maps for the Web, herausgegeben von Jack Park (Addison-Wesley, 2002), ist ein hervorragendes Buch, das sowohl die Theorie als auch die Anwendung von Topic Maps auf leicht verständliche Weise behandelt.

  

zum Seitenanfang

<< zurück vor >>

 

 

 

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

Copyright © 2006 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 "XSLT Kochbuch" 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