From our books.xml example the following demonstrates sorting the books
by listprice, using a number datatype:
xsl:param
<xsl:param
name = Qname
select = expression>
<!-- Template contents-->
</xsl:param>
The xsl:param works in a similar
way to the xsl:variable, i.e. the way its declared, using the $
sign to access it, etc. However, it allows you to pass a value into a template or an XSL stylesheet.
You can place an xsl:param element as a top-level element, to make it global; and/or as the immediate child of a template, which makes it local to that template.
You can set the value of local param elements when you refer to a template, using the xsl:with-param element, like so:
<xsl:apply-templates name="mytemplate">
<xsl:with-param name="myparam" select="'This is the value'" />
</xsl:apply-templates>
You can set the value of a global param element by setting it external to the XSL stylesheet. This should be easy, right? Probably via URL parameters, like this:
http://wwww.mysite.com/mydata.xml?myparam=BlahBlah
Sorry, wrong. Instead, you must write some JavaScript or VBScript to manually invoke the XSL template and pass parameters to it – and you could do this by reading parameters passed via your URL. This is outside the scope of this tutorial – script developers should be aware that it can be done, though, and fairly simply at that (for MSXML, check out the addParameter method of the IXSLProcessor class).
Due to the flexibility of xsl:param,
there are several places you can set the param value. The final value used in a given template is the first of these where a value is provided:
- A value passed in using the
xsl:with-param element
- A value passed in, externally to
the XSL spreadsheet, via scripting
- The local default value, set in the
local xsl:param element within the template element
- The global default value, set in the top-level xsl:param element
xsl:script
<xsl:script
language =
"language-name"
implements-prefix =
"prefix of user's namespace">
<![CDATA[
script language code
]]>
</msxsl:script>
This tag is specific to the MSXML parser. It lets you break out of the XSL syntax and embed JavaScript or VBScript code directly in your XSL document. You can then refer to functions that you have written in script language, in the rest of your XSL document.
Language-name can be: JScript, javascript, vbs, vbscript, or any other browser-supported language. If omitted or left blank, then JScript is assumed.
Implements-prefix is the prefix for the namespace that script functions are exposed to your XSL as. Of course, you can use any prefix you like, but it’s common practice to use the ‘user’ namespace. It then follows that you have to give a URI for the namespace, since by building functions that are exposed as a namespace, you are going down the track of creating your own XML vocabulary.
Here’s a simple example – let’s assume that our book list shows wholesale prices, and we want to add a 25% margin to the prices we show. (Of course, we could do this using XSL directly – but after all, this is a simple example!)
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:user="http://mycompany.com/mynamespace">
<msxsl:script language="VBScript" implements-prefix="user">
<![CDATA[
' Input: A currency value - the wholesale price
' Returns: the retail price - the inputted value plus a 20% margin,
' rounded to the nearest cent.
Function AddMargin(WholesalePrice)
AddMargin = round(WholesalePrice * 1.2, 2)
End Function
]]>
</msxsl:script>
<xsl:template match="/">
<html>
<body>
<xsl:for-each select="books/book">
<p>
<xsl:value-of select="position()"/>.
<xsl:value-of select="name"/>
Retail $<xsl:value-of
select="user:AddMargin(number(price))"/>
Wholesale $<xsl:value-of
select="number(price)"/>
</p>
</xsl:for-each>
<p>
<b>Total Retail Price =
$<xsl:value-of
select="user:AddMargin(sum(//price))"/>
</b><br/>
<b>Total Wholesale Price =
$<xsl:value-of select="sum(//price)"/>
</b>
</p>
</body>
</html>
</xsl:template>
</xsl:stylesheet>