Microsoft XML 2.5 SDK


 

Calling Script During Transformation

[This is preliminary documentation and subject to change.]

XSL currently operates at the granularity of nodes in the XML tree. Manipulations within a text node must be performed in a scripting language. An expression or single line of script can be placed in an <xsl:eval> element and the resulting text will be inserted in the output. The default scripting language is JScript® (compatible with ECMA 262 language specification), but other Active Scripting languages can be used as well. See Selecting the Scripting Language.

The following template generates a rectangle in a simple bar graph by calculating the width, left, and background-color style properties using the global variables "balance", "lowBalance", and "range".

<DIV>
  <xsl:attribute name="STYLE">
    text-align:left;
    position:relative;
    background-color:
      <xsl:eval>balance &lt; 0 ? "red" : "black"</xsl:eval>;
    width:
      <xsl:eval>(balance &lt; 0 ? -balance : balance)*100/range</xsl:eval>;
    left:
      <xsl:eval>(balance &lt; 0 ? balance-lowBalance : -lowBalance)*100/range</xsl:eval>px;
  </xsl:attribute>
</DIV>

The <xsl:eval> element inserts the results of evaluating each of the expressions into the output in place of the <xsl:eval>. In this case the values represent part of the STYLE attribute, but the result can also be inserted as element content. Since <xsl:eval> always returns text, markup cannot be inserted using this mechanism. If the text contains the special characters <, >, and &, they are escaped using character entities.

<TD STYLE="text-align:right">
  <xsl:eval>total(this)</xsl:eval>
</TD>

The above example shows the this pointer, which points to the current node being processed in the XML source. Calling DOM methods on the this object gives you access to the node's type and value, access to its attributes or children, and inspection of their values. It is possible to examine any part of the tree given the current node, generating text as a result of arbitrary calculations on the tree.

Global variables and functions can be defined in the <xsl:script> element. Usually the style sheet will contain just one <xsl:script> element, usually at the beginning or end of the style sheet.

<xsl:script><![CDATA[
  balance = 0;
  highBalance = 1500;
  lowBalance = -500;
  range = 2000;
    
  function total(e) {
    amount = parseInt(e.selectSingleNode("amount").text);
    if (e.nodeName == 'deposit' || e.nodeName == 'opening-balance')
      balance += amount;
    else
      balance -= amount;
    return formatNumber(balance, "$#,###.00");
  }
    
  function even(e) {
    return absoluteChildNumber(e)%2 == 0;
  }
]]></xsl:script>

It is recommended that you mark the XSL script blocks as character data (CDATA) as in this example. This prevents stray <'s or >'s from causing parsing errors, and automatically preserves white space. If white space is not preserved, single line comments such as // in JScript might lose their terminating return with undesirable results.

Global variables that are modified during style sheet execution should be used carefully because they can result in side effects in certain situations. As long as the style sheet is always processed in its entirety, there should be few problems, but when authoring a style sheet that can be run incrementally for purposes of minimal screen refreshes, unexpected results can occur.

Additional Functions Available to Script

In addition to the DOM, XSL provides a set of helper functions for common operations such as counting elements and formatting numbers and other data types:

Examples of these functions can be found in Formatting of Data Types Using Script, Generating Item Numbers Using Script, Calculating Totals Using Script, and Generating Links Using Script.

For security reasons, script called from XSL currently cannot instantiate COM objects.