<package>
  <job id="XSL">
  <?job debug="true"?>
  <script language="JScript">
  
  // if (window!=null) { alert("NOOP! This is for Windows Script Host 5.6 (cscript.exe)"); }
  
  // -----------------------------------------------------------------
  // from MSXML 3.x/4.x Parser SDK, modified+extended by StUs
  // cf "http://msdn.microsoft.com/xml"  MSXML 3.x/4.x + SDKs
  // cf "http://msdn.microsoft.com/scripting"  WSH 5.6 + DOCs
  //
  // FILE LOCATION:  http://www.unterstein.net/ML/WSHxslt.wsf
  //
  // USAGE:
  //      cscript //NoLogo [absPath]WSHxslt.wsf sourcefile[.xml] [stylesheet[.xsl]] [/name:value ...]
  // NOTES:
  //      cscript.exe = Windows Script Host 5.6
  //      absPath = absolute path required for Windows Script File (*.wsf) 
  //      /name:value = top-level <xsl:param name="name" select="value"/>
  //      if no stylesheet.xsl specified in commandline, tries to get 
  //      <?xml-stylesheet href="stylesheet.xsl"?> from sourcefile.xml or
  //      <xsl:stylesheet id="ID"/> from <?xml-stylesheet href="#ID"?> 
  // -----------------------------------------------------------------
  
  var oArgs = WScript.Arguments;
  var nArgs = WScript.Arguments.Named;    //  /name:value 
  var uArgs = WScript.Arguments.Unnamed;
  
  switch (uArgs.length)
- {
      case 1 : 
          var aXML = uArgs(0);
          var aXSL =  void(0);
          var fXML = (aXML.slice(aXML.lastIndexOf(".")).toLowerCase()==".xml") ? aXML : aXML+".xml" ; 
          var fXSL =  void(0);
          break;
      case 2 : 
          var aXML = uArgs(0);
          var aXSL = uArgs(1);
          var fXML = (aXML.slice(aXML.lastIndexOf(".")).toLowerCase()==".xml") ? aXML : aXML+".xml" ; 
          var fXSL = (aXSL.slice(aXSL.lastIndexOf(".")).toLowerCase()==".xsl") ? aXSL : aXSL+".xsl" ; 
          break;
      default : 
          WScript.Echo ("Usage: cscript //NoLogo [//job:XSL] [path]"+WScript.ScriptName+" [\"]sourcefile[.xml][\"] [[\"]stylesheet[.xsl][\"]] [\/param:[\"]value[\"] ...]");
          WScript.Quit(1);
          break;
  }
  
  // -----------------------------------------------------------------
  
  var Report = ['@@report'];
- var updateReport = function(s) {
      if (s instanceof Array) Report=Report.concat(s);
      else if ((typeof(s)=='string')||(s instanceof String)) Report[Report.length]=s; }
- var returnReport = function() {
      return Report.join('\r\n')+'\r\n@@\r\n'; }
  
  // -----------------------------------------------------------------
  // ActiveX DOMDocument/XSLTemplate MSXML 3/4/5/6 Initialization
  // -----------------------------------------------------------------
  
- function AXObjProgID(oPID) { 
-     for (var ProgID in oPID) {
-         try {
              var AXObj = new ActiveXObject(ProgID);
              return ProgID;
          } catch (noop) { // updateReport ("[reject] ActiveXObject ProgID \""+ProgID+"\"");
          } //End: try
      } //End: for
      WScript.StdErr.WriteLine ("[StdErr] No ActiveX DOMDocument\/XSLTemplate [MSXML ProgIDs] found, thus no XML-file(s) loadable.");
      WScript.Quit(1);
  }
  
  var AXO_DOMDoc_PID = AXObjProgID({ "MSXML2.DOMDocument.6.0":6 , "MSXML2.DOMDocument.5.0":5 , "MSXML2.DOMDocument.4.0":4 , "MSXML2.DOMDocument.3.0":3 , "MSXML2.DOMDocument":2 , "MSXML.DOMDocument":1 });
- if (nArgs.length!=0) {  // if named arguments (as parameters), variant required for createProcessor()/addParameter()
  var AXO_XSLTmp_PID = AXObjProgID({ "MSXML2.XSLTemplate.6.0":6 , "MSXML2.XSLTemplate.5.0":5 , "MSXML2.XSLTemplate.4.0":4 , "MSXML2.XSLTemplate.3.0":3 , "MSXML2.XSLTemplate":2 });
  var AXO_FTDOMD_PID = AXObjProgID({ "MSXML2.FreeThreadedDOMDocument.6.0":6 , "MSXML2.FreeThreadedDOMDocument.5.0":5 , "MSXML2.FreeThreadedDOMDocument.4.0":4 , "MSXML2.FreeThreadedDOMDocument.3.0":3 , "MSXML2.FreeThreadedDOMDocument":2 , "MSXML.FreeThreadedDOMDocument":1 });
  } // END:if
  
  // -----------------------------------------------------------------
  
- function tryProperties(o) {
  try { o.setProperty("NewParser", true); } catch(noop) { updateReport ("[reject] setProperty \"NewParser\""); }  // default false MSXML 4.0+
  try { o.setProperty("AllowDocumentFunction", true); } catch(noop) { updateReport ("[reject] setProperty \"AllowDocumentFunction\""); } // default false MSXML 6.0
  try { o.setProperty("AllowXsltScript", true); } catch(noop) { updateReport ("[reject] setProperty \"AllowXsltScript\""); }  // default false MSXML 6.0
  try { o.setProperty("ProhibitDTD", false); } catch(noop) { updateReport ("[reject] setProperty \"ProhibitDTD\""); } // default true  MSXML 6.0
  }
  
  // -----------------------------------------------------------------
  // Arguments to DOMDocument-Objects + Report
  // -----------------------------------------------------------------
  
  var oXML = new ActiveXObject(AXO_DOMDoc_PID); updateReport ("[accept] ActiveXObject ProgID \""+AXO_DOMDoc_PID+"\"");
- if (nArgs.length==0) {
  var oXSL = new ActiveXObject(AXO_DOMDoc_PID);
  } else {  // variant with parameters
  var tXSL = new ActiveXObject(AXO_XSLTmp_PID); updateReport ("[accept] ActiveXObject ProgID \""+AXO_XSLTmp_PID+"\"");
  var oXSL = new ActiveXObject(AXO_FTDOMD_PID); updateReport ("[accept] ActiveXObject ProgID \""+AXO_FTDOMD_PID+"\"");
  } // END:if
  
  // -----------------------------------------------------------------
  
  
  // -----------------------------------------------------------------
  // load XML file
  // -----------------------------------------------------------------
  
  oXML.preserveWhiteSpace = true;
  oXML.resolveExternals = true;
  oXML.validateOnParse = false;   // must be false with NewParser=true
  oXML.async = false;             // must be false with NewParser=true
  try { oXML.setProperty("NewParser", true);  }   catch(noop) { updateReport ("[reject] XML setProperty \"NewParser\""); }    // default false MSXML 4.0+
  try { oXML.setProperty("ProhibitDTD", false); } catch(noop) { updateReport ("[reject] XML setProperty \"ProhibitDTD\""); }  // default true  MSXML 6.0
  oXML.load(fXML);
  
  if (oXML.parseError.errorCode != 0)
     updateReport ("[StdErr] XML Parse Error : " + oXML.parseError.reason);
  
  // -----------------------------------------------------------------
  
  
  // -----------------------------------------------------------------
  // find FILE.XSL from PI-href-url or XSL:NODE from PI-href-id-fragment
  // -----------------------------------------------------------------
  
  var nodeXSLPI=aXSL;
  var hrefXSLPI=fXSL; 
  
- if (!nodeXSLPI) {
       oXML.setProperty("SelectionLanguage", "XPath");
       oXML.setProperty("SelectionNamespaces", "xmlns:xsl='http:\/\/www.w3.org\/1999\/XSL\/Transform'");
          var mimetypes="(contains(.,'text\/xsl') or contains(.,'text\/xml') or contains(.,'application\/xslt+xml'))";
-         var alternate={
              yes : " and    (contains(.,\"alternate='yes'\") or contains(.,'alternate=\"yes\"'))",
              no  : " and not(contains(.,\"alternate='yes'\") or contains(.,'alternate=\"yes\"'))"
              }; // [((alt)?'yes':'no')];
       nodeXSLPI = oXML.selectSingleNode("processing-instruction('xml-stylesheet')["+mimetypes+alternate.no+"]") ||
                   oXML.selectSingleNode("processing-instruction('xml-stylesheet')["+mimetypes+alternate.yes+"]"); 
       hrefXSLPI = (nodeXSLPI) ? nodeXSLPI.nodeValue.match(/href=['"](.+?)['"]/i).pop() : '' ;
       updateReport ("[StdLog] PI <?xml-stylesheet?> : \""+(hrefXSLPI||"@@none@@")+"\"");
- if (!nodeXSLPI) {
       nodeXSLPI = oXML.selectSingleNode("\/xsl:stylesheet | \/xsl:transform");
       updateReport ("[StdLog] <xsl:stylesheet\/> : "+(nodeXSLPI?nodeXSLPI.nodeName:"@@none@@")+" in sourcefile "+fXML);
  } else {
-         if (hrefXSLPI.charAt(0)=='#') { 
              hrefXSLPI=hrefXSLPI.substr(1); 
              nodeXSLPI=oXML.nodeFromID(hrefXSLPI); 
              // nodeXSLPI=oXML.selectSingleNode("id('"+hrefXSLPI+"')");
              // nodeXSLPI=oXML.selectSingleNode("\/xsl:stylesheet[id('"+hrefXSLPI+"') or @id='"+hrefXSLPI+"'] | \/xsl:transform[id('"+hrefXSLPI+"') or @id='"+hrefXSLPI+"']");
              // nodeXSLPI=oXML.nodeFromID(hrefXSLPI)||oXML.selectSingleNode("id('"+hrefXSLPI+"')")||oXML.selectSingleNode("\/xsl:stylesheet[id('"+hrefXSLPI+"') or @id='"+hrefXSLPI+"'] | \/xsl:transform[id('"+hrefXSLPI+"') or @id='"+hrefXSLPI+"']"); 
              updateReport ("[StdLog] <xsl:stylesheet\/> : "+(nodeXSLPI?nodeXSLPI.nodeName:"@@null@@")+" from ID=\""+hrefXSLPI+"\"");
          } else { fXSL=hrefXSLPI; }
      }
  }
  
  // -----------------------------------------------------------------
  
  
  // -----------------------------------------------------------------
  // load XSL file (or XML w/ xsl:stylesheet)
  // -----------------------------------------------------------------
  
  oXSL.preserveWhiteSpace = true;
  oXSL.resolveExternals = true;
  oXSL.validateOnParse = false;   // must be false with NewParser=true
  oXSL.async = false;             // must be false with NewParser=true
  try { oXSL.setProperty("NewParser", true);  } catch(noop) { updateReport ("[reject] XSL setProperty \"NewParser\""); }  // default false MSXML 4.0+
  try { oXSL.setProperty("AllowDocumentFunction", true); } catch(noop) { updateReport ("[reject] XSL setProperty \"AllowDocumentFunction\""); } // default false MSXML 6.0
  try { oXSL.setProperty("AllowXsltScript", true); } catch(noop) { updateReport ("[reject] XSL setProperty \"AllowXsltScript\""); }   // default false MSXML 6.0
  try { oXSL.setProperty("ProhibitDTD", false); } catch(noop) { updateReport ("[reject] XSL setProperty \"ProhibitDTD\""); }  // default true  MSXML 6.0
  oXSL.load(fXSL||oXML);
  
  if (oXSL.parseError.errorCode != 0)
     updateReport ("[StdErr] XSL Parse Error : " + oXSL.parseError.reason);
  
  // -----------------------------------------------------------------
  
  
  // -----------------------------------------------------------------
  // Transform XML
  // -----------------------------------------------------------------
  
  try
- {
-     if (nArgs.length==0) {
          WScript.Echo (oXML.transformNode(oXSL));
      } else {
          tXSL.stylesheet = oXSL;
          var pXSL = tXSL.createProcessor();
          pXSL.input = oXML;
          // -----------------------------------------------------------------
          // named arguments for <xsl:param name="name" select="value"/>
          // -----------------------------------------------------------------
          var aName = new RegExp().compile("^\/(\\w+?):");
-         for (var idx=0; idx<oArgs.length; idx++) {
              if (aName.test(oArgs(idx))) pXSL.addParameter(RegExp.$1,nArgs.Item(RegExp.$1));
          } // END:for
          // -----------------------------------------------------------------
          // NOOP!?:  for (var aNameStr in WScript.Arguments.Named) { ... WScript.Arguments.Named.Item(aNameStr) ... }
          // -----------------------------------------------------------------
          pXSL.transform();
          WScript.Echo (pXSL.output);
      } // END:if
  }
  catch(err)
- {
     updateReport ("[StdErr] XML\/XSL Transform Error : " + err.number + "* " + err.description);
  }
  
  // -----------------------------------------------------------------
  
  
  // -----------------------------------------------------------------
  // Report + Quit
  // -----------------------------------------------------------------
  
  WScript.StdErr.WriteLine ( returnReport() ); WScript.Quit(0);
  
  // -----------------------------------------------------------------
  
  </script>
  </job>
  </package>