Microsoft XML 2.5 SDK


 

Selecting the Scripting Language

[This is preliminary documentation and subject to change.]

Script in a style sheet can be written in any Active Scripting language. JScript® (compatible with ECMA 262 language specification) is used by default, but other languages can be specified by setting the language attribute on the <xsl:stylesheet> element. This attribute accepts the same values as the language attribute on the HTML <SCRIPT> element.

For example, here is the script block of the style sheet of the stock-sorter sample rewritten in Microsoft® Visual Basic® Scripting Edition (VBScript).

<xsl:script xmlns:xsl="http://www.w3.org/TR/WD-xsl" language="VBScript"><![CDATA[
  Function totalVolume(root)
    Dim total
    Dim volumes
    total = 0
    Set volumes = root.selectNodes("portfolio/stock/volume")
    For Each node in volumes
      total = total + node.nodeTypedValue
    Next
    totalVolume = formatNumber(total, "0") & " million shares"
  End Function
    
  Function averageChange(root)
    Dim total
    Dim count
    Dim formatedNumber
    total = 0
    Set percents = root.selectNodes("portfolio/stock/percent")
    count = percents.length
    
    For Each node In percents
      total = total + node.nodeTypedValue
    Next
  
    formatedNumber = formatNumber(total/count, "1") 
    averageChange = formatedNumber & "%"
  End Function
]]></xsl:script>

The language attribute specifies that the function declarations are in VBScript instead of the default JScript.

Setting the language on the <xsl:stylesheet> element changes the scripting language for the entire style sheet. Most style sheets will only set the attribute there. The following style sheet is written largely in VBScript, and imports the script block above using an external entity.

<?xml version="1.0"?>     
<!DOCTYPE xsl:stylesheet [
  <!ENTITY externalScript SYSTEM "externalScript.xml">
]>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl" language="VBScript">
  &externalScript;
  
  <xsl:template match="/">
    <HTML>
      <HEAD>
        <STYLE>
          BODY {margin:0}
          .bg {font:8pt Verdana; background-color:purple; color:white}
          H1 {font:bold 14pt Verdana; width:100%; margin-top:1em}
          .row {font:8pt Verdana; border-bottom:1px solid #CC88CC}
          .header {font:bold 9pt Verdana; cursor:hand; padding:2px; 
                   border:2px outset gray}
          .up {background-color:#DDFFDD;}
          .down {background-color:#FFDDDD;}
        </STYLE>
      </HEAD>
      
      <SCRIPT LANGUAGE="VBScript"><xsl:comment><![CDATA[
        Dim stylesheet, source, sortField
        Function sort(field)
          sortField.value = field
          listing.innerHTML = source.documentElement.transformNode(stylesheet)
        End Function
      ]]></xsl:comment></SCRIPT>
      <SCRIPT LANGUAGE="VBScript" for="window" event="onload"><xsl:comment><![CDATA[
        Set stylesheet = document.XSLDocument
        Set source = document.XMLDocument
        Set sortField = document.XSLDocument.selectSingleNode("//@order-by")
      ]]></xsl:comment></SCRIPT>
      
      <BODY>
        <TABLE width="100%" cellspacing="0">
          <TR>
            <TD class="bg"/>
            <TD class="bg">
              <H1><xsl:value-of select="portfolio/description"/>
                for <xsl:apply-templates select="portfolio/date"/></H1>
              <DIV>Average change: <B><xsl:eval>averageChange(me)</xsl:eval></B></DIV>
              <DIV>Total volume: <B><xsl:eval>totalVolume(me)</xsl:eval></B></DIV>
            </TD>
          </TR>
          <TR>
            <TD class="bg" width="120" valign="top">
              <P>Click the column headers to sort by that field.</P>
              <P>Demonstration of custom formatting of data typed values and
              local reapplication of the style sheet.</P>
              <P>Stocks losing more than 5% indicated in red.  Stocks gaining
              value indicated in green.</P>
            </TD>
            <TD class="bg" valign="top">
              <DIV id="listing"><xsl:apply-templates select="portfolio"/></DIV>
            </TD>
          </TR>
        </TABLE>    
      </BODY>
    </HTML>
  </xsl:template>
  
  <xsl:template match="portfolio">
    <TABLE STYLE="background-color:white">
      <THEAD>
        <TD width="200"><DIV class="header" onClick="sort('name')">Company</DIV></TD>
        <TD width="80"><DIV class="header" onClick="sort('symbol')">Symbol</DIV></TD>
        <TD width="80"><DIV class="header" onClick="sort('price')">Price</DIV></TD>
        <TD width="80"><DIV class="header" onClick="sort('change')">Change</DIV></TD>
        <TD width="80"><DIV class="header" onClick="sort('percent')">%Change</DIV></TD>
        <TD width="80"><DIV class="header" onClick="sort('volume')">Volume</DIV></TD>
      </THEAD>
      <xsl:for-each select="stock" order-by="symbol">
        <TR>
          <xsl:for-each select="change">
            <xsl:if expr="me.nodeTypedValue &gt; 0">
              <xsl:attribute name="class">up</xsl:attribute>
            </xsl:if>
          </xsl:for-each>
          <xsl:for-each select="percent">
            <xsl:if expr="me.nodeTypedValue &lt; -5">
              <xsl:attribute name="class">down</xsl:attribute>
            </xsl:if>
          </xsl:for-each>
          <TD><DIV class="row"><xsl:value-of select="name"/></DIV></TD>
          <TD><DIV class="row"><xsl:value-of select="symbol"/></DIV></TD>
          <TD><DIV class="row" STYLE="text-align:right"><xsl:apply-templates select="price"/></DIV></TD>
          <TD><DIV class="row" STYLE="text-align:right"><xsl:apply-templates select="change"/></DIV></TD>
          <TD><DIV class="row" STYLE="text-align:right"><xsl:apply-templates select="percent"/></DIV></TD>
          <TD><DIV class="row" STYLE="text-align:right"><xsl:apply-templates select="volume"/></DIV></TD>
        </TR>
      </xsl:for-each>
    </TABLE>
  </xsl:template>
  <xsl:template match="date" language="JScript">
    <xsl:eval>formatDate(this.nodeTypedValue, "MMMM dd',' yyyy")</xsl:eval>
              at <xsl:eval>formatTime(this.nodeTypedValue, "hh:mm tt")</xsl:eval>
  </xsl:template>
  
  <xsl:template match="price | change">
    <xsl:eval language="JScript">formatNumber(this.nodeTypedValue, "$0.00")</xsl:eval>
  </xsl:template>
  
  <xsl:template match="percent">
    <xsl:if language="JScript" expr="this.nodeTypedValue &gt; 0">+</xsl:if>
    <xsl:eval language="JScript">formatNumber(this.nodeTypedValue, "0.0")</xsl:eval>%
  </xsl:template>
  
  <xsl:template match="volume">
    <xsl:eval language="JScript">formatNumber(this.nodeTypedValue * 1000000, "#,###,###")</xsl:eval>
  </xsl:template>
  
</xsl:stylesheet>

Although it should be rarely needed, the language attribute can be used on other elements in order to use multiple Active Scripting languages within a single style sheet, as in the above example. The following elements support the language attribute:

The language setting for these elements is inherited from the nearest ancestor with a language attribute.