Still, the elements are so convenient that we will cover them here. After all, most Visual Basic programmers will be using the MSXML library anyway. It is the most widely available implementation on the Windows platform. Microsoft has stated that they will continue support for the eval and script elements in later versions, so if you plan to stick with Microsoft, there is no reason for not using eval.
So what is it then? The eval element allows you to generate a text node in the destination document using script. If you have created Active Server Pages or Windows Scripting Host scripts before, you will be familiar with the ActiveX Scripting Engine. This is a generic scripting platform that several languages can be plugged into. Standard available scripting languages are VBScript and JScript.
The script node can hold a piece of script that can hold function definitions. These can be called from the eval element.
This way you can do something like this:
<xsl:template match="TEMP[@scale='F']">
<xsl:eval language="VBScript">
Celsius(this.getAttribute('value'))
</xsl:eval>
</xsl:template>
<xsl:script language="VBScript"><![CDATA[
Function Celsius(fDegrees)
Celsius = (fDegrees - 32) * 5 / 9
End Function
]]>
</xsl:script>
If this template is used on an XML element like this:
<TEMP scale="F" value="80"/>
It would generate this in the output document:
26.66666667
Using this extension, more complex calculations can be placed inside the script block. As scripting languages will sometimes contain characters that are not allowable in XML, it is good practice to place the script blocks in CDATA nodes.
The eval element contains a function call to the Celsius function in the script element. The return value of the function is outputted by the eval element to the destination document. Note the use of this to refer to the context node.
Functions defined inside a script element can be called from an eval element, but also from attributes that are evaluated as an expression (see for example the if element in the section "Control of Flow").
Commands
apply-templates
The xsl:apply-templates element is the most typical example of a command element (an element that starts the processing of a node). Because it is so important, we have already covered it before. However, there are more ways to invoke another template.
apply-imports
When we described the import element, we saw that sometimes the main XSLT document contains templates that match the same XPath expression as one of the templates in the imported document. In these cases, the template in the main document overrides the imported template. Using this feature, XSLT authors can create new transformations based on existing ones, extending them with new templates or changing existing templates. If you are familiar with object-oriented design, you will like this idea.
If you are overruling a template in your document, you will often want to invoke the original template from your newer implementation. Let's look at an example.
The source document contains data about books and the data about a book's author is always coded in an AUTHOR tag. A typical AUTHOR tag looks like this:
<AUTHOR firstname="Teun" lastname="Duynstee" initials="L.W.A."
nobelprize="no"/>
Several different XSLT transformations exist in our organization, all dealing with book information. Some repeating transformations were put together in a stylesheet that is frequently imported into other XSLT documents. It looks like this:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- many other templates -->
<xsl:template match="AUTHOR">
<xsl:value-of match="@firstname"/>
<xsl:text> </xsl:text>
<xsl:value-of match="@lastname"/>
</xsl:template>
</xsl:stylesheet>
The template transforms any matched AUTHOR attribute to a text node consisting of the firstname attribute joined to the lastname attribute by a single space. In our sample source, the output would be something like:
Teun Duynstee
Now we want to write an XSLT document that will transform XML data about a book into an HTML document. In the HTML document, the author's full name should appear, formatted in italics. We already have a transformation rule that creates the full name of the author, but it does no formatting. We can now import the standard author transformation and modify it slightly in our overriding template:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:import href="booklib.xsl"/>
<xsl:template match="AUTHOR">
<I><xsl:apply-import/></I>
</xsl:template>
</xsl:stylesheet>
The new template just specifies the literal element I that will cause italic fonts in HTML, and inside the I element, it calls the template which it overrules from the import. The result would be this:
<I>Teun Duynstee</I>
call-template
The call-template element is another element that can be used to organize the templates in your document. For calling a template with call-template, the template must have a name attribute. It works like apply-templates, but there is no change of context node. In fact call-template is very much like calling a function in a procedural programming language. Here's an example:
<xsl:template name="fullname output">
<xsl:value-of match="@firstname"/>
<xsl:text> </xsl:text>
<xsl:value-of match="@lastname"/>
</xsl:template>
<xsl:template match="AUTHOR[@nobelprize='no']">
<xsl:call-template name="fullname output"/>
</xsl:template>
<xsl:template match="AUTHOR[@nobelprize='yes']">
<B>
<xsl:call-template name="fullname output"/>
</B>
</xsl:template>
The two templates for AUTHOR elements (for Nobel prize winners and others) both call the same template for formatting the attributes into a full name string.
If a template is called by name the match attribute is ignored and vice versa.
What if Several Templates Match?
If the XSLT processor is searching for a template to use for transforming a certain node, it's possible that it will find several templates that match (and are of the same mode - check the coming section on 'Modes'). The XSLT specification defines a set of rules to determine which template is the most appropriate. These rules are quite complex, but the general idea is not so hard to understand. In order of increasing importance:
- An imported template is less important than one associated with the document (i.e. not imported).
- The template imported later is more important than one imported earlier.
- A high priority template is more important than a low priority template.
- A more specific match attribute is more important than a more general matching expression.
When the processor starts searching for an appropriate template, it first creates a set of all available templates. From this set, it removes all templates that don't match. After that it removes templates that have a lower import precedence than others. When several documents are imported, and especially when imports are nested, things can get rather complicated. What the processor does is to build a tree of imported documents. Suppose Document A imports B and C (in that order), B imports D and C imports E, the tree would look like this:

Note how Document B is lower in the tree than Document C. This is because imports that occur later in the document prevail over imports done before. The higher in the tree a document is (in an absolute sense, not in a hierarchical sense), the higher the import precedence. The built-in templates are treated as if they are imported at the very beginning of the main document and therefore have the lowest priority of all.
Continued...