If I'm understanding what you're trying to do is to call an XSL extension function, that is written in JavaScript. Here's an example .wsf that takes as an input an xml file, and an xsl file, and outputs the transformed result.
It illustrates how to call a javascript extension function. For this example the javascript extension function is a "objDate" object that converts an Epoch date, into a formatted string.
Hope this helps, otherwise I've wasted my evening trying to help you out!
Sorry this is long, but there's no other way :)
Here's what's included...
complete .WSF file (save to t.wsf)
sample XML (save to t.xml)
sample XSL (save to t.xsl)
the output.
To run the example, make sure you have MSXML installed then run
cscript t.wsf t.xml t.xsl
Sample t.wsf file
<package>
<job id="t1">
<script language="JScript">
try {
var objArgs = WScript.Arguments;
if( objArgs.length < 2) {
WScript.Echo( "Usage: xform.wsf file.xml, file.xsl" );
WScript.Quit( 1 ); // no FTP
}
var xml = loadXML( objArgs(0) );
var xsl = loadXML( objArgs(1) );
var aParms = new Array();
aParms["testparm"] = "XSL Rocks!";
var xmlResult = transform( xml, xsl, aParms );
// just dump out the result
WScript.Echo( xmlResult.xml );
} catch ( err ) {
WScript.Echo( err.description );
}
// Creates a DOM document, with the proper parameters set, version 1.1
function newXML() {
var strDOMObject = "MSXML2.FreeThreadedDOMDocument";
var xml = new ActiveXObject( strDOMObject );
xml.setProperty( "SelectionLanguage", "XPath" ); // i.e. not XSLT
xml.resolveExternals = 0;
xml.validateOnParse = 0;
xml.preserveWhiteSpace = true;
try {
// configure the document to allow for Microsoft extensions within XPath
xml.setProperty("SelectionNamespaces", " xmlns:ms='urn:schemas-microsoft-com:xslt' xsl='http://www.w3.org/1999/XSL/Transform' :html='http://www.w3.org/1999/xhtml' " );
xml.setProperty("NewParser", true ); // 2 - 4x performance improvement, NO async, NO DTD validation
} catch (e) {
delete e;
}
return xml;
}
// loads XML from disk, with exceptions
function loadXML( strFileName ) {
var xml = this.newXML();
var strErrMsg = '';
try {
if( !xml.load( strFileName ) ) {
processLoadError( xml );
}
} catch( e ) {
strErrMsg = "Error loading " + strFileName + ":" + e.description;
e.description = strErrMsg;
throw e;
}
return xml;
}
function processLoadError( xml ) {
var strErrMsg = '';
strErrMsg = xml.parseError.reason;
if( xml.parseError.srcText != "" )
strErrMsg += "Source: " + xml.parseError.srcText + "\r\n";
if( xml.parseError.line != 0 )
strErrMsg += "Line: " + xml.parseError.line + "\r\n";
if( xml.parseError.linepos != 0 )
strErrMsg += "Position: " + xml.parseError.linepos + "\r\n";
throw new Error( xml.parseError.errorCode, strErrMsg );
}
function transform( xml, xsl, aParms ) {
try {
var strDOMObject = "MSXML2.FreeThreadedDOMDocument";
var strTemplateObject = "MSXML2.XSLTemplate";
var xslt = new ActiveXObject(strTemplateObject );
var xmlReturn = new ActiveXObject( strDOMObject );
var xslProc;
xslt.stylesheet = xsl;
xslProc = xslt.createProcessor();
xslProc.input = xml;
// create and add in the extension object
var dt = new objDate();
xslProc.addObject( dt, "urn:dt");
if( aParms ) {
for( key in aParms ) {
if( (typeof(aParms[key]) != "undefined") && ( aParms[key] != null ) ) {
xslProc.addParameter( key, aParms[key] );
}
}
}
xslProc.transform();
if( !xmlReturn.loadXML( xslProc.output ) ) {
processLoadError( xmlReturn );
}
return xmlReturn;
} catch( e ) {
e.description = "Error transforming XML: " + e.description;
throw e;
}
}
// Simple Date Object, add in your own methods here...
function objDate() {
// Methods, to be called from XSLT
this.DateParse = objDate_DateParse;
}
function objDate_DateParse( objNodeList) {
if( !objNodeList.length )
return ""; // no date from the XSL, return an empty string
// XSL passes in a collection, typically only 1, but for this exmaple, just get the last one
for( i = 0; i < objNodeList.length; i++ ) {
var strDate = objNodeList(i).text;
}
var dt = new Date( parseInt( strDate ) );
var strReturn = (dt.getMonth() + 1 ) + "/" + dt.getDate() + " " + dt.getHours() + ":" + dt.getMinutes();
return strReturn;
}
</script>
</job>
</package>
Next a sample XML, with an Epoch @dt in each row.
<xml>
<row id='123' dt='1605666152744'/>
<row id='234' dt='1605766152744'/>
<row id='345' dt='1605866152744'/>
</xml>
Then the XSL that calls the javascript extension object "dt". Note that you have to declare the namespace at the top of the XSL.
<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:dt="urn:dt" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:param name='testparam'/>
<xsl:variable name='list' select='//row'/>
<xsl:template match='/'>
<div>
<h1>Test XSL with Date Extension - <xsl:value-of select='$testparam'/></h1>
<table class='table'>
<thead>
<tr>
<th>Name</th>
<th>Date</th>
</tr>
</thead>
<tbody>
<xsl:for-each select='$list'>
<tr>
<td><xsl:value-of select='@id'/></td>
<td><xsl:value-of select='dt:DateParse( @dt )'/></td>
</tr>
</xsl:for-each>
</tbody>
</table>
</div>
</xsl:template>
</xsl:stylesheet>
Finally the result, note the formatted dates, from the Epoch Dates.
<div xmlns:dt="urn:dt" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<h1>Test XSL with Date Extension - </h1>
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Date</th>
</tr>
</thead>
<tbody>
<tr>
<td>123</td>
<td>11/17 21:22</td>
</tr>
<tr>
<td>234</td>
<td>11/19 1:9</td>
</tr>
<tr>
<td>345</td>
<td>11/20 4:55</td>
</tr>
</tbody>
</table>
</div>