Recipe13.4.Generating Web Sites from XTM Topic Maps


Recipe 13.4. Generating Web Sites from XTM Topic Maps

Problem

You want to capture knowledge about a subject in a Topic Map. You want to do so in a way that facilitates generation of a web site from the Topic Map using XSLT.

Solution

The solution is based on the Cogitative Topic Maps Web Site (CTW) framework introduced to readers in XML Topic Maps, edited by Jack Park (Addison Wesley, 2002). Extreme Markup Languages initially presented this work in 2000.

The CTW uses the following mapping from topic map elements to HTML:

Topic map element

HTML rendering

Topic map

Web site

Topic

Web page

Topic associations

Site map

Topic occurrences

Images, graphics, text, HTML fragments, etc.

Topic names

Page headers, titles, lists, and hyperlink titles


The Topic Map we create covers the subject of algorithms and, specifically, sorting algorithms. Knowledge represented in this topic map was aggregated from information resources gathered on the Internet and organized as class-subclass associations between algorithms and occurrences of types descriptions, demonstrations, and code examples in several programming languages.

Once the subject and content of the web site were decided, the ontology of the web site subjects and objects followed quite naturally. The CTW ontology layer consists of two main parts: classification of web site's topic subjects and classification of topic characteristics that provide web-page content.

Both classifications play a very important role in controlling a web site's look and feel. Topic types control web-page layouts, and types of topic characteristics control the styling of web-page elements and building blocks. The results are depicted in Figure 13-3.

Figure 13-3. The look and feel of a generated site


The following subsections describe the subjects of the Sorting Algorithms web site.

Sorting algorithms

The main subjects of our web site are the sorting algorithm's various subclasses:

<topic >      ... </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>

The full version of the topic map and XSLT scripts is available online at http://www.cogx.com/ctw. This section provides only some fragments to illustrate example instructions.


Each sorting algorithm can have its own subclassesfor example, you can count four variations of in-place-sort, each of which may in turn have its own subclasses:

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

The National Institute of Standards and Technology (NIST) maintains an excellent web site on algorithms (http://www.nist.gov/dads/) and collects information about various computational algorithms. It maintains a web page devoted to each algorithm. This topic map uses URLs of those pages as algorithm subject identifiers of algorithms:

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

Besides playing roles in class-subclass associations with other algorithms, sorting algorithms have other topic characteristics such as base names and occurrences.

In this topic map, sorting algorithms have names under which they are commonly recognized:

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

Sometimes they also have alternative names represented as base names in the also-known-as scope:

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

The algorithm's description is represented as a topic occurrence of type description in the scope of the description's source. The following code is a citation from the National Institute of Standards and Technology web site (thus specified in the scope of the nist topic) that can also read, "In the context of NIST, insertion sort is described as . . . "

     <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 to algorithm demonstrations such as applets and animations are represented as topic occurrences of type demonstration:

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

You can also record links to sorting algorithms implementations and represent them in your topic map as occurrences of type code sample specified in the scope of a programming language in which they are implemented. Programming languages is the other class of topics represented on your web site that constitute an orthogonal navigational dimension:

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

That is all the information about algorithms that we chose to represent. You will use it to build page headers, links to related algorithms, descriptions, links to pages on the Web defining that algorithm, links to algorithm demonstrations, and code samples with cross links to programming languages in which these examples are implemented.

Programming languages

You only need be interested in the fact that program languages are, in their names and definitions, instances of the programming language class:

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

The programming language page shown in Figure 13-4 gathers links to code samples implemented in that language and cross links to the implemented algorithms.

Figure 13-4. Programming languages page


Root topic

In the CTW framework, root is the topic whose subject is indicated by the topic map document itself. In topic map terms, root topic reifies the topic map document to which it belongs:

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

When topic maps merge in CTW, this topic is added to the scopes of all topic characteristic assignments. More importantly, this topic corresponds to the home or default page of the CTW web site.

This example displays its hyperlinked name in the upper-left corner of all pages on your web site:

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

This is the place to store topic map annotations and assertions about the topic map. This example is limited to the description of project and copyright metadata:

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

The root page shown in Figure 13-5 shows only the project's description as an introduction to the web site.

Figure 13-5. Root page of the sort algorithms web site


Page elements and layout

First, define the root variable that represents the root topic: as described earlier, this topic is indicated by the containing topic map document:

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

The same node could be matched using the subjectIndicator key that matches topics using addresses of resources that indicate them:

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

First, generate the default page by calling the root-page layout template for the root topic:

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

Next, the code generates web pages for every subclass of the sorting algorithm. Here you call the algorithm-page layout template with basic sorting algorithm as this parameter. The template recursively calls itself to iterate over subclasses of all subclasses:

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

The stylesheet generates pages for every instance of a programming language by calling the plang-page layout template:

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

The instanceOf key returns all topic instances of a class based on the class topic's hashed IDs:

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

The topicByID key returns all topic elements based on a given topic's hashed IDs:

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

As you might have noticed in the screenshots, all three layout templates have a common subdivision into four square areas. The common main page-building template controls this. First, instruct the processor to create an output file relative to the output folder specified in the $out-dir parameter, and create the TITLE header with the current topic's base name in the unconstrained scope. The latter is achieved by instantiating template matching topic elements in the label mode. Then start the page's subdivision into four parts. In the upper-right corner, create a hyperlink to the home page whose label is the name of root topic in the unconstraint scope. The topic-matching template in the link mode accomplishes this task. In the upper-right part of the page, you'll have a selection of links to programming languages pages. Iterating over all instances of programming-language topic creates this. In the lower-left quarter of the page under the home page link, print the part of the site map corresponding to the sorting algorithms' classification. Finally, in the main part of the page in the lower-right quarter, output the main-page content pertinent to the current topic submitted to the page template as content parameter:

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

The previous template uses the baseName-matching template in the label mode:

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

The baseName matching template in the link mode creates a hyperlink to the topic's web page:

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

Later in the code, you will use the baseName-matching template in the subject-indicator mode. This template creates a hyperlink to a resource indicating the matched topic:

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

The sitemap template iterates over all subclasses of the sort topic, creates hyperlinks to pages corresponding to derived algorithms, and recursively calls itself to iterate over subclasses of the subclasses:

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

The classRef key used by the site map template uses the ID of a given topic to match superclass-subclass associations for which the topic plays super-class role:

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

Later in the code, you will use a subClassRef key that also matches superclass-subclass associations, but this time using member where the topic plays sub-class role:

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

Now you are ready to consider the three layout templates.

The root-page layout template is very simple. Call the page template described earlier and send it the generated HTML code for occurrences of type description in the content parameter:

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

The plang-page layout template is a bit more involved. It has a title composed of the name of the current topic followed by the name of topic's type. Then a subject identity line points to a place elsewhere on the Web where the topic's subject is defined. Following it are topic descriptions, if any. Iterate and output a link for each code occurrence implemented in the current language. In square brackets following the resource, place a link to the sorting algorithm implemented in this resource:

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

The plang-codes key used earlier matches all occurrences in the topic map by any of their scope themes:

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

The algorithm-page layout template comes last. Its title is composed of the current topic's name followed by also-known-as names in square brackets. The subject identity line is followed by the list of superclasses, if any, from which the current sorting algorithm inherits. Then you'll find one or more sorting algorithm descriptions, followed by the list of links to algorithm demonstration occurrences and the list of code samples with cross links to implementing programming languages in square brackets. On the bottom of the page, you'll list subclasses or variations, if any, of the current sorting algorithm. Finally, the algorithm-page layout template calls itself recursively to output pages for subclasses of all its subclasses:

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

Discussion

Topic Maps is a technology that accumulates and manages knowledge about real-world domains. In this case, you represented relationships between algorithms and other objects and resources. If you are careful to follow the conventions of CTW, you'll be able to drive the creation of a web site from the topic map source.

In this solution, you were limited to just a few types of objects and relationships between them. Real-life applications are much more complicated. The main idea was to demonstrate the power and tremendous opportunities provided by the CTW framework.

In the CTW framework, a single topic map document controls both the content and structure of an entire web site. Proper CTW topic map architecture provides robust and intuitive maintenance of links between web pages, web-page content, and metadata. Web sites built according to CTW are easily merged and immune to dead links. XSLT offers a consistent look and feel, platform independence, and reusability.

You do have to pay to get all these benefits: the CTW framework requires you to think of your content in terms of topics, topic characteristics, and associations. This approach limits you to creating content only in the limits of the chosen ontology, but it helps keep the knowledge represented on the web site well organized and navigable.

XSLT enables the CTW because it provides a modular and maintainable means to transform and stylize the knowledge contained in the topic map. Dynamic CTW solutions created with XSLT scale up to several thousand topics, and static solutions are limited only by the available disk space.

See Also

XML Topic Maps: Creating and Using Topic Maps for the Web, edited by Jack Park, (Addison Wesley, 2002) is an excellent book that covers both the theory and application of topic maps in a very accessible manner.

You can find a good collection of links to resources about topic maps at http://www.dmoz.org/Computers/Artificial_Intelligence/Knowledge_Representation/Topic_Maps/.

The author maintains a site at http://www.cogx.com/ctw that further discusses topic maps and the cogitative topic maps framework. Slides from the Extreme Markup Languages presentation of CTW are available at http://www.cogx.com/Extreme2000/.




XSLT Cookbook
XSLT Cookbook: Solutions and Examples for XML and XSLT Developers, 2nd Edition
ISBN: 0596009747
EAN: 2147483647
Year: 2003
Pages: 208
Authors: Sal Mangano

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net