The Tamino JavaScript API

Although XSLT can generate all sorts of output from an original XML file, it does not provide a binding of the displayed elements to the original XML elements. When an XML document is converted into HTML, it is not possible to modify the HTML elements on the screen and automatically reflect the changes back to the original XML document. In fact, XSLT does not provide any facilities for processing end-user input. We have to employ other technology in order to do this.

One suitable technology is JavaScript. JScript, Microsoft's version of JavaScript, provides features that make it possible to access Tamino directly from the client's web page. The Tamino JavaScript API utilizes those features. Consequently, it can only be used for clients running on a Microsoft Windows platform with the Microsoft Internet Explorer.

Apart from this restriction, the Tamino JavaScript API offers lightweight access to all relevant Tamino functions. You can query, insert, update and delete objects and control transactional behavior directly from the client.

In the following example, we use the Tamino JavaScript API to make an interactive index web page. The stylesheet jazzMusician-index.xsl generates such a page that lists all the jazz musicians stored in the encyclopedia collection. When the user moves the mouse over these entries, the corresponding artist's albums are shown in a separate text area:

graphics/mus-ix.png

This is achieved by generating an event handler onmouseover="javascript:displayAlbums()" for each entry and passing the musician's ID to the function. The function first connects to Tamino, issues a query for a collaboration corresponding to the musician's ID, then uses the result element of each collaboration document to query for album documents. Finally, the title of each album is written into a special display area (implemented as <div id="albumArea">). Here is the complete code:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
      xmlns="http://www.softwareag.com/tamino/doc/examples/models/jazz/encyclopedia"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes"/>
<!-- define constant for tamino query string -->
<xsl:variable name="query">
http://localhost/servlets/com.softwareag.tamino.api.servlet.TaminoFilter/tamino/jazz/encyclopedia?_XQL=
</xsl:variable>
<xsl:variable
  name="ency">http://localhost/tamino/jazz/encyclopedia</xsl:variable>
<!-- define constant for pass-thru string -->
<xsl:variable name="sheet">&amp;_xslsrc=xsl:stylesheet/</xsl:variable>
<!-- Just a single rule for the root node -->
<xsl:template match="/">
<!-- Generate HTML document root -->
<html>
  <head>
    <SCRIPT LANGUAGE="JavaScript"
            SRC="{concat($ency,'/scripts/TaminoLib.js'}}"></SCRIPT>
    <script language="JavaScript"><![CDATA[
function displayAlbums(jmid,mname) {
// create title
 var aText = "Albums of "+mname+":<br>";
// construct database and collection name
// (just to have a single point of maintenance)
 var dbname=
]]>
<xsl:value-of select="concat('&quot;',$ency,'&quot;;')"/>
<![CDATA[
 // prepare query
 var QueryVal="e:collaboration[e:jazzMusician='"+jmid+"']";
 var pageSize=0;
 // create Tamino client
 var QueryObj = new TaminoClient(dbname, pageSize);
 // issue query
 var QueryResult = QueryObj.query(QueryVal);
 // strip off Tamino packaging
 var xqlResult=QueryResult.getResult();
 if (xqlResult) {
   // get collaboration nodes
   var collaborations=xqlResult.childNodes;
   // loop through each collaboration
   for (var i=0; i<collaborations.length; i++) {
     var collabSelected = collaborations.item(i);
     // get result node
   var title=albumSelected.getElementsByTagNameNS(
             "http://www.softwareag.com/tamino/doc/examples/models/jazz/encyclopedia",
                                                                             "title");
     // get album node
     var album=result.item(0).childNodes.item(0);
     // get albumNo
     var albumNo=album.getAttribute("albumNo");
          // construct query
     var QueryVal2="e:album[@albumNo='"+albumNo+"']";
     // issue query
     var QueryResult2 = QueryObj.query(QueryVal2);
     // strip off Tamino packaging
     var xqlResult2=QueryResult2.getResult();
     if (xqlResult2) {
       // get album nodes
       var albums=xqlResult2.childNodes;
       // loop through all album nodes
       for (var j=0; j<albums.length; j++) {
         var albumSelected = albums.item(j);
         // get title node
         var title=albumSelected.getElementsByTagNameNS(
               "http://www.softwareag.com/tamino/doc/examples/models/jazz/encyclopedia",
                                                                               "title");
   // add title node data to output string
         aText = aText+"<br>"+title.item(0).childNodes.item(0).data;
       }
     }
   }
 }
 // write output string into album area
 document.all.albumArea.innerHTML = aText;
}
  ]]></script>
  <title>The Jazz Index</title>
</head>
<body bgcolor="#000000" text="#FFFFCC" link="#FFFFCC" vlink="#C0C0C0">
  <div id="albumArea" style="position:absolute; top:150px; left:430px;
   width:200px; height:250px; background-color:#FFFFCC; color:#000000;
   font-family:Arial; font-size:9pt; font-weight:bold; padding:10px;">
    <layer id="lay1" bgcolor="#FFFFCC">
      Albums:
    </layer>
  </div>
  <h1>The Jazz Index</h1>
  <hr/>
  <xsl:for-each select="//e:jazzMusician">
    <xsl:variable name="mname">
      <xsl:value-of select="e:name/e:first"/>
        <xsl:if test="e:name/e:middle">
          <xsl:text> </xsl:text>
          <xsl:value-of select="e:name/e:middle"/>
        </xsl:if>
       <xsl:text> </xsl:text>
       <xsl:value-of select="e:name/e:last"/>
    </xsl:variable>
    <p>
      <a href=
"{concat($query,'e:jazzMusician[@ID=&quot;',@ID,'&quot;]',$sheet,'jazzMusician.xsl')}"
         onmouseover="javascript:displayAlbums('{@ID}','{$mname}')">

         <xsl:value-of select="$mname"/>
      </a>
    </p>
  </xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>