The Microsoft XSLT services (and some other manufacturers too) allow JavaScript (and other script languages) to be run from within an XSL transform. This can be necessary for certain functions. The string processing in XPath functions are limited and having access to the JavaScript string functions can be a project saver. With this extension the full power of JavaScript regular expressions and their ability to intelligently replace strings is available in XPath expressions. This could be very useful when handling attribute values such as dates and phone numbers.
This article describes how to call JavaScript from within an XSLT using the Microsoft extensions. These extensions are available in the MSXML 4.0, which is the version installed with eWebEditPro+XML. As of eWebEditPro 5.1, MSXML 4.0 is no longer installed. MSXML 6.0 is used instead.
JavaScript can be used in XSLT by following these steps:
-
Declare the "msxsl" namespace asshown.
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
-
Declare a namespace for your script, for example,
xmlns:js="urn:custom-javascript"
-
(Optional) Omit the prefixes from the output, for example,
exclude-result-prefixes="msxsl js"
-
Write the JavaScript in the msxsl:script element, for example,
<msxsl:script language="JavaScript" implements-prefix="js">
<![CDATA[
:
>
</msxsl:script>
-
Call your JavaScript function in an XPath expression, for example,
<xsl:value-of select="js:escapeUnicode(string(.))"/>
Example
This example converts non-ASCII characters to escaped JavaScript codes that are ASCII and UTF-8 compatible. For example, a Unicode char U12488 will be changed to "\u30c8".
The sections critical to using JavaScript are in bold. Note that the prefix, "js" and the namespace "urn:custom-javascript" are arbitrary, but it is helpful to have meaningful values.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:js="urn:custom-javascript"
exclude-result-prefixes="msxsl js"
>
<xsl:template match="text()">
<!-- escapes unicode chars to be safe for JavaScript -->
<xsl:value-of select="js:escapeUnicode(string(.))"/>
</xsl:template>
<msxsl:script language="JavaScript" implements-prefix="js">
<![CDATA[
function escapeUnicode(strText)
// Escape strText to be ASCII, safe for native encoding or UTF-8.
{
var strConverted = "";
var lenText = strText.length;
var numCharCode = new Number(0);
for (var i = 0; i < lenText; i++)
{
numCharCode = strText.charCodeAt(i);
if (numCharCode <= 0x7f)
{
// ASCII, no conversion
strConverted += strText.charAt(i);
}
else if (numCharCode <= 0xff)
{
// single byte Latin1
strConverted += "\\x" + toHexString(numCharCode, 2);
}
else
{
// double byte Unicode
strConverted += "\\u" + toHexString(numCharCode, 4);
}
}
return strConverted;
}
// private
function toHexString(numValue, minLength)
// Convert numValue (Number object) to a hexidecimal representation string of
// minimum length (minLength) padded with leading zeros as necessary.
{
if (typeof numValue != "number")
{
return "Bad numValue, type: "+ typeof numValue;
}
if (typeof minLength != "number")
{
return "Bad minLength, type: " + typeof minLength;
}
var strValue = numValue.toString(16); // convert to hex string
// Ensure min len
while (strValue.length < minLength)
{
strValue = "0" + strValue;
}
return strValue;
}
>
</msxsl:script>
<!-- ... more templates go here ... -->
</xsl:stylesheet>