Increasing Performance by Using the XSLTemplate Object

 

Calling the transformNode or transformNodeToObject method does not always allow for maximum performance, because the style sheet object passed into the method is a DOM node, and must be recompiled every time the method is called. Compiling the style sheet means setting up all its template rules in an executable state. If you need to call these methods repeatedly, you should cache the compiled XSLT style sheet in an XSLTemplate object, and use this object to perform your transformation. This helps reduce overhead, and increases the performance of your XSLT application.

This section demonstrates the use of the XSLTemplate object with a sample Web application for reading book reviews. For simplicity, we'll assume that a small bookstore puts all its book reviews in a single XML file, BookReview.xml. To read the review of particular book, a reader submits a book title from our ReviewReader application. This triggers a transformation — that is, the application applies an XSLT style sheet to the XML file, with the new book title as its input. The review of the book is the output HTML.

This example uses the following three source files: BookReview.xml, BookReview.xsl, and BookReview.htm. These files are listed below.

Example: BookReview Web Application Using XSLTemplate

The following is an example.

BookReview.xml

<?xml version='1.0'?>
<book-review>
   <book>
      <title>A Good Book</title>
      <author>The Good Writer</author>
      <publisher>The Publisher</publisher>
      <date>A Good Day</date>
      <Review>
          <title>A Good Book</title> by <author>The Good Writer</author>, 
          published by <publisher>The Publisher</publisher> on <date>A 
          Good Day</date>, is indeed a good book.
      </Review>
   </book>
   <book>
      <title>A Bad Book</title>
      <author>The Bad Writer</author>
      <publisher>The Publisher</publisher>
      <date>A Bad Day</date>
      <Review>
         <title>A Bad Book</title> by <author>The Bad Writer</author>, 
         published by <publisher>The Publisher</publisher> on <date>A Bad 
         Day</date>, is indeed a bad book.
      </Review>
   </book>
   <book>
      <title>A So-so Book</title>
      <author>The So-so Writer</author>
      <publisher>The Publisher</publisher>
      <date>A So-so Day</date>
      <Review>
         <title>A So-so Book</title> by <author>The So-so Writer</author>, 
         published by <publisher>The Publisher</publisher> on 
         <date>A So-so Day</date>, is indeed a so-so book.
      </Review>
   </book>
</book-review>

BookReview.xsl

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:param name="title" />

  <xsl:template match="/">
    <HTML>
      <HEAD>
      </HEAD>
      <BODY>
         <xsl:apply-templates select="//book[title=$title]" /> 
      </BODY> 
    </HTML>
  </xsl:template>

  <xsl:template match="book">
     <table>
        <TR>
          <TD style="font-weight:bold">Title:</TD>
          <TD><xsl:apply-templates select="title"/></TD>
        </TR>
        <TR>
          <TD style="font-weight:bold">Author:</TD>
          <TD><xsl:apply-templates select="author"/></TD>
        </TR>
        <TR>
          <TD style="font-weight:bold">Date:</TD>
          <TD><xsl:apply-templates select="date"/></TD>
        </TR>
        <TR>
          <TD style="font-weight:bold">Publisher:</TD>
          <TD><xsl:apply-templates select="publisher"/></TD>
        </TR>
        <TR>
          <TD style="font-weight:bold">Review:</TD>
          <TD><xsl:apply-templates select="Review"/></TD>
        </TR>
     </table>

  </xsl:template>

  <xsl:template match="title">
      <SPAN><xsl:value-of select="."/></SPAN>
  </xsl:template>

  <xsl:template match="author">
      <SPAN><xsl:value-of select="."/></SPAN>
  </xsl:template>
  <xsl:template match="publisher">
      <SPAN><xsl:value-of select="."/></SPAN>
  </xsl:template>
  <xsl:template match="date">
      <SPAN><xsl:value-of select="."/></SPAN>
  </xsl:template>

  <xsl:template match="review">
      <P><xsl:apply-templates /></P>
  </xsl:template>

</xsl:stylesheet>

BookReview.htm

<HTML>
<HEAD>
   <SCRIPT language="jscript">
      var objSrcTree, ObjXSLT, objCache;

      function init()
      {
         objSrcTree = new ActiveXObject('MSXML2.DOMDocument.6.0');
         objSrcTree.async = false;
         objSrcTree.load('BookReview.xml');

         objXSLT=new ActiveXObject('MSXML2.FreeThreadedDOMDocument.6.0');
         objXSLT.async = false;
         objXSLT.load('BookReview.xsl');

         objCache   = new ActiveXObject("Msxml2.XSLTemplate.6.0");
         objCache.stylesheet = objXSLT;

         output.innerHTML = "Select a book above to read the review!";
      }

      function show(title)
      {
         var objXSLTProc = objCache.createProcessor();
         objXSLTProc.input = objSrcTree;
         objXSLTProc.addParameter("title", title, "");
         objXSLTProc.transform();
         output.innerHTML = objXSLTProc.output;
      }

   </SCRIPT>
</HEAD>

<BODY onload="init();">
   <DIV>Books reviewed: 
        <A HREF="javascript:show('A Good Book')">A Good Book</A>
        <A HREF="javascript:show('A Bad Book')">A Bad Book</A>
        <A HREF="javascript:show('A So-so Book')">A So-so Book</A>
   </DIV>
   <DIV id="output" style="margin:1em"></DIV>
</BODY>
</HTML>

As shown above, to use the XSLTemplate object to cache a compiled XSLT style sheet and perform transformations, your must perform the following tasks.

To perform your transformations with XSLTemplate
  1. Load the appropriate XSLT style sheet as a FreeThreadedDOMDocument object. Be sure to set the async property of this object to "false".

  2. Create an XSLTemplate object. Set its stylesheet property to the XSLT style sheet created in the Step 1. Notice that loading and caching are carried out in the init() function when the HTML page is first loaded.

  3. Load the source XML document as a DOMDocument object. In this example, this XML document is loaded once in the init() function as well. In other applications, this is not necessarily the case.

  4. Create an XSLProcessor object for each transformation. The following steps are needed to complete the transformation.

  5. Assign the source XML document object to the input property of the XSLProcessor object created in Step 3.

  6. Call the addParameter method on the XSLProcessor object to pass any required global variables used in the XSLT style sheet. In the example above, the style sheet uses a title parameter to select a book with the specified title: <xsl:apply-templates select="//book[title=$title]" />.

  7. Optionally, assign an output stream object (such as a recordset object in ADO or a Response object in ASP) to the output parameter of the XSLProcessor object. Choose this option if you do not want to use the default output stream object.

  8. Call the transform method on the XSLProcessor object to start the transformation.

  9. Retrieve the result of the transformation from the output parameter of the XSLProcessor object.

In addition to passing a parameter to an XSLT style sheet, as described in Step 6, you can also pass an object (a DOM node), if necessary. For more information about how to pass an object to an XSLT style sheet by way of an XSLProcessor object, see the XSLProcessor.addObject method.