XML

Converting XSL to XSLT

As mentioned previously, we need to update the XSL style sheets to make them compliant to the W3C XSLT specification. Specifically, we'll need to change XSL and related namespaces. A new official XSLT namespace is available: http://www.wc.org/1999/XSL/Transform. The 2.6 and higher versions of the XML parser can recognize both the new namespace and the existing namespace http://www.w3.org/TR/WD-xsl. Since <xsl:eval>and <xsl:script> blocks are not supported in XSLT, they have to be converted to an XSLT-conformant mechanism. We'll also need to add JScript implementations of XTLRuntime functions where necessary, since the XTLRuntime object extends the W3C standard. What's more, we will also have to replace all the operators with their XML equivalents. For example, $lt$ will need to be replaced with &lt;, $gt$ will have to be replaced with &gt;, and so forth. The operators that have no XML equivalent, such as ieq, will require you to write special functions. Although this sounds like it can be a lot of work, Microsoft actually provides a converter called XSL to XSLT Converter. The converter is zipped into a file named Xsltconv.exe. The file can be downloaded at Microsoft's Web site. The zip file contains three files: Xsl-xslt-converter.xslt, Readme-xslt.txt, and Convert.js. You can run the Convert.js program from the DOS prompt. The format is as follows:

  PathToConvert.js/convert.js PathToXSLFile/
   XSLFileName [XSLTFileName]

The parameter is optional. The program will perform the required conversion from an XSL file to an XSLT file. If you convert the XSL document discussed in "The for-each and apply-templates elements" section of this chapter to an XSLT document, you will find some minor changes as described below.

The stylesheet element has been changed to the following:

  <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      version="1.0"
      xmlns:msxsl="urn:schemas-microsoft-com:xslt"
      xmlns:local="#local-functions"
      xmlns:xql="#xql-functions"
      xmlns:auto-ns1="http://www.w3.org/TR/WD-xsl">
  <!-- [XSL-XSLT] Updated namespace, added the required
    version attribute, and added namespaces necessary for
    script extensions. -->

Since Internet Explorer 5 was released prior to the current standard, there was no way to know what the final namespace would be in the standard. Thus, the namespace we have been using with the Internet Explorer 5 XSL documents is different from the W3C namespace.

When working with Internet Explorer 5, you can use the Internet Explorer 5 namespace in your XSL document (<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl"> ); but when you use this namespace, your XSL documents will not work with other applications that recognize XSLT. On the other hand, if you use XSLT documents with the namespace from the W3C standard, these documents will not currently work in Internet Explorer 5.

You can also see the msxsl and local namespaces in the stylesheet element above. These namespaces will be used to define a set of default functions that will replace all the functions in the Microsoft XSL documents that are not part of the standard. In this case, we are not using any of these functions.

The next two additions from the converter are as follows:

  <!-- [XSL-XSLT] Explicitly apply the default (and only)
       indent-result behavior -->
  <xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />
  <!-- [XSL-XSLT] Simulate lack of built-in templates -->
  <xsl:template match="@*|/|node()" />

The XSLT document has an output element that can be used to define how the information should be output. This element has been added to the document. Values for this element have also been added, as well as a default template that will select all nodes in the tree.

These are the only changes that were made to the original document. When we discussed XSL above, we used the XPath syntax. As mentioned previously, the XPath syntax was also the same as the XSL syntax. Therefore, nothing needed to be changed since XSLT uses XPath. Thus, for a simple XSL document you will only need to make minor changes. This means that you can currently write XSL documents that work with Internet Explorer 5, and they will only require minor changes when you convert them to XSLT documents.

If you are using more complex XSL documents, such as documents referencing the Internet Explorer 5 XTLRuntime extended methods, you will find that you have to make major modifications to your document. If you try to convert the XSL document we made to test the XTLRuntime object using the conversion program, you will find that there are major changes. This is because this entire XSL document uses the XTLRuntime object, which contains functions that are not part of the W3C standard. One of the conversions looks as follows:

  nodeName: <!-- [XSL-XSLT] Converted xsl:node-name to
     xsl:value-of --><xsl:value-of select="name()" />
  Absolute Child Number:
     <!-- [XSL-XSLT] Converted xsl:eval to xsl:value-of -->
     <xsl:value-of select="local:eval_1_2_2_2_2_2_4(.)" />

In XSLT, the nodeName function is no longer used; instead, we use the name function as the criteria for the select attribute of the value element. The second change looks very weird, but it's actually very simple. The value for the select attribute of the value-of element is local:eval_1_2_2_2_2_2_4(.). The local prefix defines the namespace, which points to a location at the bottom of the generated XSLT document. The base eval_1_2_2_2_2_2_4 is a Java function that is defined in the local namespace. The parameter that is being passed into the function is the dot (.), or the current element. The eval_1_2_2_2_2_2_4 function looks as follows:

  function eval_1_2_2_2_2_2_4(_contextNodeList)
      {
         var __this = _contextNodeList.item(0);
         return absoluteChildNumber(__this);
      }

The function takes the first element from the node and returns the absoluteChildNumber using another Java function, as shown below:

  function absoluteChildNumber(pNode)
      {
         var n = 1;
         while (pNode == pNode.nextSibling)
            n++;
         return n;
      }

Notice that the eval_1_2_2_2_2_2_4 function takes a NodeList object, while the absoluteChildNumber takes a node object. The absoluteChildNumber function uses the DOM object to get the correct number. Any application that uses a DOM object as specified in the W3C DOM standard, and also is capable of reading XSLT documents, will be able to use these Java script functions. Thus, these are generic XSLT documents.

You can use XSLT with Internet Explorer 5 today, but you will have to do a little work either on the server or on the client. You can use Microsoft's implementation of DOM to transform an XML document using an XSLT document. We will do that in the section "Using the XML DOM to Work with XSLT and XSL" later in this chapter. First we'll take a look at the XPath and XSLT Functions.