js/vbs/html/hta and more hybrids and chimeras in cmd/bat

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
penpen
Expert
Posts: 1991
Joined: 23 Jun 2013 06:15
Location: Germany

Re: js/vbs/html/hta hybrids and chimeras in cmd/bat

#16 Post by penpen » 23 Apr 2014 04:23

@Liviu: Just impressive.

You may reduce the incompatabilities with xml by removing the "^"
character to use the ":" only (then used 2 times, then... merely an optical one; tested only on WinXp home 32 bit):

Code: Select all

<?xml : version="1.0" encoding="UTF-8"
: ?>
<!------------------------- : cmd ----

penpen

Liviu
Expert
Posts: 470
Joined: 13 Jan 2012 21:24

Re: js/vbs/html/hta hybrids and chimeras in cmd/bat

#17 Post by Liviu » 24 Apr 2014 00:56

siberia-man wrote:

Code: Select all

"%~f0?.wsf"
Very interesting trick allowing to run a batch file as wsf scenario. I tried to embed wsf into bat/cmd but all my attempts bumped to impossibility to run bat file as wsf (as it is possible for vbs or js scenarios). Is there source where I could learn more about it? Seems it uses some bug in cmd.exe (or wsh, or hidden feature of one of them).
I don't know any more than what I posted. Train of thought was that I had just noticed in the previous post that WSH parses the command line in a very unorthodox way. Then I wondered, what are the chances that there might be other oddities in that ad-hoc parser.

On a second look, the keys seem to be "?" as a delimiter, and ".wsf" as the extension, for example "%~f0?xyz.wsf" works as well. Probably an unintended (or possibly undocumented backdoor) related to parameter-passing URLs. In our paranoid times, could well be that someone someday sees it as a security risk and decides to "fix" it.

npocmaka_ wrote:I was wondered if it's possible to register the ".bat" extension to WSH as a dummy extension language and how eventually that could be used but didn't reach so far yet (it's still in my list with crazy ideas).
Crazy or not, but I tried to register ".cmd" as a "WSFFile" type, and didn't work for me ;-)

penpen wrote:You may reduce the incompatabilities with xml by removing the "^"
character to use the ":" only (then used 2 times, then... merely an optical one; tested only on WinXp home 32 bit):

Code: Select all

<?xml : version="1.0" encoding="UTF-8"
: ?>
<!------------------------- : cmd ----
You have a point, but the ":" colons in the declaration are technically an XML violation already.

WSF files don't seem to be 100% compliant XML, for example the following prolog also works, even though it has free text between the <?xml> declaration and the root <package> node.

Code: Select all

<?xml :: version="1.0" encoding="UTF-8" ?> ---------------------------- cmd ---
@echo off
echo cmd
cscript //nologo "%~f0?xyz.wsf" //job:JS //job:VBS
exit /b
----------------------------------------------------------------------- wsf ---
<package>
  <job id="JS"> <!------------------------------------------------------ js -->

Also, according to http://msdn.microsoft.com/en-us/library/dzfdccyf(v=vs.84).aspx if there is no <?xml> declaration then the parser will ignore everything inside <script> blocks until the </script> end tag. So the choice comes down to:
- <?xml> and CDATA, where the script code must avoid literal ']]>', or
- no <?xml> and no CDATA, where the script code must avoid literal </script>

Neither alternative is 100% clean XML, both rely on special WSF parsing, so in the end it's a matter of style preference.

Liviu

penpen
Expert
Posts: 1991
Joined: 23 Jun 2013 06:15
Location: Germany

Re: js/vbs/html/hta hybrids and chimeras in cmd/bat

#18 Post by penpen » 24 Apr 2014 03:24

Maybe the xml authors add a "default/global namespace access" (to attributes, somewhere) in the future, so you can add colons without using a namespace prefix.
So this has the best chances to become valid xml:

Code: Select all

<?xml :version="1.0"
      :encoding="windows-1252" ?><![CDATA[ cmd
:: ...
]]>
(Does anybody know someone in the W3C, or where one could present this proposal? ... Although i doubt they change it only of windows batch..., so whoever presents it to W3C should add more advantages of such feature. :wink: )

penpen

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: js/vbs/html/hta hybrids and chimeras in cmd/bat

#19 Post by dbenham » 26 Apr 2014 09:30

:D :D :D :D :!:
Really sweet discovery to be able to cleanly embed wsf within batch.
Liviu wrote:So the choice comes down to:
- <?xml> and CDATA, where the script code must avoid literal ']]>', or
- no <?xml> and no CDATA, where the script code must avoid literal </script>

Neither alternative is 100% clean XML, both rely on special WSF parsing, so in the end it's a matter of style preference.

I don't see either limitation as being a significant problem, and I find the latter option much simpler and less verbose.


Dave Benham

Liviu
Expert
Posts: 470
Joined: 13 Jan 2012 21:24

Re: js/vbs/html/hta hybrids and chimeras in cmd/bat

#20 Post by Liviu » 26 Apr 2014 16:47

penpen wrote:Maybe the xml authors add a "default/global namespace access" (to attributes, somewhere) in the future
It crossed my mind that ":" could be mis-parsed as a namespace:variable with both strings empty, then expanded to a null token and ignored. Or maybe the parser is so fixated on watching for "version=" that it ignores anything in between, I don't know. As far as getting XML to formalize ":" as valid syntax, I agree with your ;-) ;-)

dbenham wrote:Really sweet discovery to be able to cleanly embed wsf within batch.
Inasmuch as we call "%~f0.wsf" clean ;-) it's also a way to embed VBScript more "cleanly" than some of the alternatives.

Liviu

P.S. Just when I thought there isn't much left to learn about cmd/js hybrids, here is a neat one-liner from "Peter Schwier" in a comment at http://blogs.msdn.com/b/joshpoley/archive/2008/01/15/running-jscript-in-a-cmd-file.aspx which "daisy-chains" JScript from batch.

Code: Select all

@if (false)==(false) @cscript //nologo //e:jscript "%~f0" %* & goto :eof @end
WScript.Echo("JScript code, guaranteed to always run under CScript.");

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: js/vbs/html/hta hybrids and chimeras in cmd/bat

#21 Post by dbenham » 27 Apr 2014 13:24

Liviu wrote:
dbenham wrote:Really sweet discovery to be able to cleanly embed wsf within batch.
Inasmuch as we call "%~f0.wsf" clean ;-) it's also a way to embed VBScript more "cleanly" than some of the alternatives.

Precisely why I am so excited by the technique.

I've updated my StackOverflow hybrid batch/VBS Q&A with this superior method. I've included a link back to this thread, as well as a link to your specific post announcing the WSF discovery.


Dave Benham

penpen
Expert
Posts: 1991
Joined: 23 Jun 2013 06:15
Location: Germany

Re: js/vbs/html/hta hybrids and chimeras in cmd/bat

#22 Post by penpen » 28 Apr 2014 06:41

I assume the wsf parser treats the "<?xml ... ?>" element similar as a processing instruction, where ":" characters are allowed.
Except using the name "xml", "xmL", ... "XML" these processing instructions are defined for XML, too:
http://www.w3.org/TR/2008/REC-xml-20081126/#sec-pi.

Code: Select all

<?batch  :: 
@echo off
set /P "All character combinations allowed without ?^>, but this is easy to escape." <nul
>CON echo avoid a ?^> at the end after a question mark: ?
exit /b
?>
<root/>
So
Liviu wrote:the parser is so fixated on watching for "version=" that it ignores anything in between
:) .

In the end: Double colon would be valid xml if the W3C could be convinced to treat the xml declaration (<?xml ... ?>) just as a reseved processing instruction,
instead of disallowing "xml", "xmL", ..."XML" as beeing a name for a processing instruction.
(I think one could find better arguments to implement this into the xml standard instead of what i've written in my above posting.)

penpen

Liviu
Expert
Posts: 470
Joined: 13 Jan 2012 21:24

Re: js/vbs/html/hta hybrids and chimeras in cmd/bat

#23 Post by Liviu » 28 Apr 2014 20:37

@Dave, that's a nice well rounded writeup. And thanks for the credit, though accurate attributions are often times hard to come by in batch world. The arcane batch syntax - and the lengths we go to and pervert it further ;-) - makes searches difficult to try and locate the original sources. One can't google for "::'<SUB>@" where <SUB> is 0x1A, for example. Or for "<!-- :" for that matter - actually this one has its own funny sub-story. When I posted my "?.wsf" trick I still had a nagging feeling that I had seen something like "<!-- :" before, and it certainly wasn't on the Russian forum in siberia-man's link. Then, while writing this post today, I tried a random search for "xml comment" on dostips, and there it was "<!-- ::" at http://www.dostips.com/forum/viewtopic.php?p=14694#p14694 in the first hit. Quite remarkable, isn't it, to have remembered it in the first place, and then find it a couple of years later. Except, then I looked more closely and ...oops, it was a post of my own ;-)

@penpen, right, but '<?xml' is alot more restrictive than PIs in general. The W3C reference docs are not the friendliest to read ;-) but the case of the '<?xml' declaration seems clearly cut. It's a pretty special PI and it must be at the very top of the file, if present at all. It can only contain the version/encoding/standalone tags - each with its own rigid format - and nothing else but whitespace before the closing '?>'. I don't see any room (or backdoor ;-)) where one could slip a ':' in that grammar (http://www.w3.org/TR/2008/REC-xml-20081126/#NT-EncodingDecl). It might be possible to insert an ':' in other PIs, but the point of the exercise here was to make the XML more compliant by adding the '<?xml' declaration - allowing, for example, an explicit encoding to be specified. I don't see that working and, barring that, I tend to agree with Dave's assessment that no '<?xml' (and therefore no 'CDATA' required, or supported) remains the simpler solution.

Liviu

penpen
Expert
Posts: 1991
Joined: 23 Jun 2013 06:15
Location: Germany

Re: js/vbs/html/hta hybrids and chimeras in cmd/bat

#24 Post by penpen » 29 Apr 2014 04:41

I don't see any room (or backdoor ) where one could slip a ':' in that grammar (http://www.w3.org/TR/2008/REC-xml-20081 ... codingDecl). It might be possible to insert an ':' in other PIs, but the point of the exercise here was to make the XML more compliant by adding the '<?xml' declaration - allowing, for example, an explicit encoding to be specified.
My post above should only explain why the ":" characters are allowed in a wsf (at least from my point of view);
the above code should not be seen as an example to improve the XML conformity - but maybe someone sees a solution when reading it (so i posted the above).
(Don't get me wrong: I try to improve that aspect, as i really could need that actually - for my private use only i could organize my whole batch/vbs/... files using a xml database, so i am able to search for specific things better and faster.)

So actually (state of the art) the only well formed xml file (unless I am mistaken) is your (Liviu's) version without the xml declaration with some comments:

Code: Select all

<!-- :: cmd   
@echo off
echo cmd
cscript //nologo "%~f0?.wsf" //job:JS //job:VBS
exit /b
-->
<package>
   <job id="JS">
      <script language="VBScript">
' avoid ]] in this VBScript
' <![CDATA[
sub vbsEcho()
   WScript.Echo "cmd.js.vbs"
end sub
' ]]>
      </script>
      <script language="JScript">
// avoid ]] in this JScript
// <![CDATA[
WScript.Echo("cmd.js");
vbsEcho();
// ]]>
      </script>
   </job>
   <job id="VBS">
      <script language="JScript">
// avoid -- in this JScript
// <!--
function jsEcho() { WScript.Echo("cmd.vbs.js"); }
// -->
      </script>
      <script language="VBScript">
' avoid -- in this VBScript
' <!--
WScript.Echo "cmd.vbs"
call jsEcho
' -->
      </script>
  </job>
</package>
Automatic xml version 1.0 detection, as no xml declaration is used; automatic character encoding based on
http://www.w3.org/TR/xml11/#sec-guessing-no-ext-info,
but as batch scripts have to be executable, only ANSI files are possible recognised as UTF-8, so no characters in [0x80:0xFF].

In my above post i forgotten to write that microsoft doesn't use a xml parser for that:
They are using a (very simple, not fully implemented) SGML parser, where all names for processing instructions are allowed;
this also explains all other "special" syntax possible.
they've added some additional tests for the <?xml ... ?> element put haven't watched for the ":".

penpen

Edit: Added the state of the art part.
Edit2: Clarified an ambiguous verbalization.
Last edited by penpen on 30 Apr 2014 14:28, edited 1 time in total.

penpen
Expert
Posts: 1991
Joined: 23 Jun 2013 06:15
Location: Germany

Re: js/vbs/html/hta hybrids and chimeras in cmd/bat

#25 Post by penpen » 29 Apr 2014 08:06

If you want to access the batch as cdata, too you might do something like that:

Code: Select all

<!-- :: cmd as the first JScript
:: --><package><job id=":batch"><script language="JScript">
@if (true == false) @end /*<![CDATA[
@echo off
echo cmd
cscript //nologo "%~f0?.wsf" //job:JS
exit /b
]]>
*/
      </script>
   </job>
   <job id="JS">
      <script language="JScript">
// <![CDATA[
WScript.Echo("cmd.js");
vbsEcho();
// ]]>
      </script>
   </job>
</package>

penpen

Liviu
Expert
Posts: 470
Joined: 13 Jan 2012 21:24

Re: js/vbs/html/hta hybrids and chimeras in cmd/bat

#26 Post by Liviu » 29 Apr 2014 21:25

@penpen, sorry if something came off the wrong way about my "funny story", surely dind't mean it. What I wanted to actually say is that proper attribution is often difficult in batch world and, while I always try to give credit where credit is due, misses or mistakes happen. After all, this was a case where I couldn't recognize my _own_ former little contribution until accidentally finding it on a search - and I am pretty sure it's not the only case. So, anybody who notices me forgetting to properly cite 'prior art' please just point me to the sources, and I'll be happy to correct and amend. As for sharing, seeing something I posted being used and/or built upon is its own reward of sorts, so everyone feel free to tweak/improve/hack to death any of it.

penpen wrote:In my above post i forgotten to write that microsoft doesn't use a xml parser for that:
They are using a (very simple, not fully implemented) SGML parser, where all names for processing instructions are allowed;
this also explains all other "special" syntax possible.
they've added some additional tests for the <?xml ... ?> element put haven't watched for the ":".
I think that's the case, indeed. Microsoft's actual XML parser throws an error if you insert a stray ":" in the <?xml .. ?> declaration of, for example, an XSLT file, while WSH lets it pass for WSF files.

penpen wrote:If you want to access the batch as cdata, too you might do something like that:
I don't think that works. It doesn't give errors in batch since since "<![CDATA[" is inside a false conditional, and "]]>" is after "exit /b". It also doesn't give errors in JScript since it's all inside a /*<![CDATA[ ... ]]>*/ comment. But it doesn't work as a CDATA section proper. Try for example inserting a ":: </script>" line right above "@echo off". That raises an error "Windows Script Host: The end tag does not match the start tag : job" which shows that </script> was actually parsed as an XML tag - which wouldn't happen inside a recognized CDATA section. As far as I can tell, proper CDATA parsing requires an <?xml .. ?> declaration at the top.

Liviu

penpen
Expert
Posts: 1991
Joined: 23 Jun 2013 06:15
Location: Germany

Re: js/vbs/html/hta hybrids and chimeras in cmd/bat

#27 Post by penpen » 30 Apr 2014 01:01

Liviu wrote:
penpen wrote:If you want to access the batch as cdata, too you might do something like that:
I don't think that works. [...]. But it doesn't work as a CDATA section proper. Try for example inserting a ":: </script>" line right above "@echo off". That raises an error "Windows Script Host: The end tag does not match the start tag : job" which shows that </script> was actually parsed as an XML tag - which wouldn't happen inside a recognized CDATA section. As far as I can tell, proper CDATA parsing requires an <?xml .. ?> declaration at the top.
I've described too short recently: Sorry for that.
I didn't meant this from the ".WSF" parsers view.
I meant this from a XML parsers view, so you can transform it using XSLT (accessing the pure batch data inside the CDATA section).

penpen

Liviu
Expert
Posts: 470
Joined: 13 Jan 2012 21:24

Re: js/vbs/html/hta hybrids and chimeras in cmd/bat

#28 Post by Liviu » 04 May 2014 00:31

Liviu wrote:WSF files don't seem to be 100% compliant XML [...] if there is no <?xml> declaration then the parser will ignore everything inside <script> blocks until the </script> end tag
penpen wrote:In my above post i forgotten to write that microsoft doesn't use a xml parser for that: They are using a (very simple, not fully implemented) SGML parser, where all names for processing instructions are allowed
Liviu wrote:As far as I can tell, proper CDATA parsing requires an <?xml .. ?> declaration at the top.
penpen wrote:I didn't meant this from the ".WSF" parsers view. I meant this from a XML parsers view

Good point, thanks for making it. WSH (cscript/wscript) seems to use its own internal XML parser for WSF files, other than and different from the MSXML or XMLLITE builtins. The WSF handling of CDATA is only one of its non-conforming oddities - technically, a missing <?xml .. ?> at the top should default to and behave the same as <?xml version="1.0" encoding="utf-8"?>. But it also has issues with <!DOCTYPE> declarations, entitites and probably more.

Yet, it's still possible to write XML that the WSF parser lets pass, and "reparse" it later in embedded code. Following post is an example of a hybrid cmd+wsf+xslt where the batch code calls into embedded JScript code, which in turn loads an XSLT stylesheet also embedded in the same file, and returns the result as text to the calling batch code.

Liviu

Liviu
Expert
Posts: 470
Joined: 13 Jan 2012 21:24

Re: js/vbs/html/hta hybrids and chimeras in cmd/bat

#29 Post by Liviu » 04 May 2014 01:50

It has come up before that the "<!-- ::" syntax (or "<!-- :") could be used to build hybrid cmd+xml files. There have been examples of it for cmd+html/mshta/wsf, but I don't recall a cmd+xslt one. This post seeks to cover that missing part. Anyone not interested in xml/xslt might as well stop here, and skip over the rest.

The two techniques below provide for:
1. a hybrid cmd+xslt batch file with an embedded stylesheet, used to process an xml file of known format using an external command line XML processor of user's choice;
2. a hybrid cmd+wsf+xslt all-in-one batch file with an embedded stylesheet, and also the necessary jscript code to apply it to a given xml, using just Windows' builtin parser, without relying on external processors.

Think it's easier to follow if I start with a - completely made up, still somewhat believable - use case. Suppose one had an XML file holding file information and respective hashes, such as...

Code: Select all

<?xml version='1.0' encoding='UTF-8'?>
<dfxml xmloutputversion='1.0'>
  <fileobject>
    <filename>file-0.txt</filename>
    <hashdigest type='MD5'>a3037a8c309f79fbccc1cfb0bce59634</hashdigest>
    <hashdigest type='SHA1'>c2f71e783ed2b5e78d30917a7363ed041de87d02</hashdigest>
  </fileobject>
  <fileobject>
    <filename>dir-1\file-1-1.txt</filename>
    <hashdigest type='MD5'>2ae67a9bf2060a55033796e4ef0d023e</hashdigest>
    <hashdigest type='SHA1'>49eb490983196ca2b829b0885c8880afd9e52f5d</hashdigest>
  </fileobject>
  <fileobject>
    <filename>dir-2\file-2-1.txt</filename>
    <hashdigest type='MD5'>c83a699edda408fec4340e3f7aa5acfd</hashdigest>
    <hashdigest type='SHA1'>a83b85c8cca34c484d31ec116247583453a29dab</hashdigest>
  </fileobject>
  <fileobject>
    <filename>dir-2\file-2-2.txt</filename>
    <hashdigest type='MD5'>21bb58475e5a9b7146730e6eb8e74bb1</hashdigest>
    <hashdigest type='SHA1'>76418189163e89d9fc38fdf1acaa36e15046d86f</hashdigest>
  </fileobject>
</dfxml>
...and needed to convert it to a flat text format like...

Code: Select all

a3037a8c309f79fbccc1cfb0bce59634* file-0.txt
2ae67a9bf2060a55033796e4ef0d023e* dir-1\file-1-1.txt
c83a699edda408fec4340e3f7aa5acfd* dir-2\file-2-1.txt
21bb58475e5a9b7146730e6eb8e74bb1* dir-2\file-2-2.txt
...where incidentally the xml file is a trimmed down dfxml format such as generated by hashdeep/md5deep, and the text is in the de-facto standard accepted by most every md5sum clone.

Such a conversion between formats would not be a trivial batch task - due to potential extra/irrelevant information in the input file, whitespace (spaces/tabs/newlines) tolerance in xml, the '<>' characters that are special to batch, etc. On the other hand, extracting the very specific information needed from the xml is just what XSLT was made for, and all it takes is a straightforward "transformation" (which is what "T" in XSLT stands for). Note that the XSLT as written does not include the '*' binary marker after MD5s, and puts quotes around the filename - both formatting issues will be taken care of in the batch code later down.

Code: Select all

<?xml version='1.0' encoding='iso-8859-1'?>
<!DOCTYPE xsl:stylesheet [<!ENTITY eol "&#x26;#xA;">]>
<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
<xsl:output method='text' encoding='iso-8859-1'/>
<xsl:strip-space elements='*'/>
<xsl:template match='dfxml/fileobject'>
  <xsl:value-of select="concat(hashdigest[@type='MD5'],' &quot;',filename,'&quot;&eol;')"/>
</xsl:template>
</xsl:stylesheet>

To run an XSLT on an XML file, one needs an XML parser/processor. An older, yet functioning one, is Microsoft's own MSXSL.EXE http://www.microsoft.com/en-us/download/details.aspx?id=21714. With that in hand (i.e. somewhere in the PATH, or in the current directory), the following works - assuming the files above are saved as 'dfx.xml' and the XSLT 'dfx2md5.xslt' respectively.

Code: Select all

C:\tmp>for /f "tokens=1,*" %X in ('msxsl "dfx.xml" "dfx2md5.xslt"') do @echo %~X* %~Y
a3037a8c309f79fbccc1cfb0bce59634* file-0.txt
2ae67a9bf2060a55033796e4ef0d023e* dir-1\file-1-1.txt
c83a699edda408fec4340e3f7aa5acfd* dir-2\file-2-1.txt
21bb58475e5a9b7146730e6eb8e74bb1* dir-2\file-2-2.txt

This, however, requires having the external XSLT file available, and MSXSL.EXE available. The rest of this post is about removing those restrictions, one by one - and both codes return the same output as the one above.

1. hybrid cmd+xslt batch file with an embedded stylesheet, used to process an xml file of known format using an external command line XML processor of user's choice

Code: Select all

<!-- :: dfx2md5-msXsl.cmd :: converts dfxml file to md5sum format using msXsl.exe
@echo off
for /f "tokens=1,*" %%X in ('msxsl "%~1" "%~f0"') do echo %%~X* %%~Y
goto :eof & rem -->

<!-- embedded stylesheet identical to standalone one, except for
     the <?xml?> declaration which cannot be inserted at the very top of the file -->
<!-- <?xml version='1.0' encoding='iso-8859-1'?> -->
<!DOCTYPE xsl:stylesheet [<!ENTITY eol "&#x26;#xA;">]>
<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
<xsl:output method='text' encoding='iso-8859-1'/>
<xsl:strip-space elements='*'/>
<xsl:template match='dfxml/fileobject'>
  <xsl:value-of select="concat(hashdigest[@type='MD5'],' &quot;',filename,'&quot;&eol;')"/>
</xsl:template>
</xsl:stylesheet>

2. hybrid cmd+wsf+xslt all-in-one batch file with an embedded stylesheet, and also the necessary jscript code to apply it to a given xml, using just Windows' builtin parser, without relying on external processors

Code: Select all

<!-- :: dfx2md5.cmd :: converts dfxml file to md5sum format - - - - - .cmd  - -
@echo off
for /f "tokens=1,*" %%X in ('cscript //nologo "%~f0?.wsf" "%~1"') do (
  echo %%~X* %%~Y
)
goto :eof & rem -->

<job> <!--  - - - - - - - - - - - - - - - - - - - - - - - - - - - -   .wsf  -->

<xslt id='default'> <!--  - - - - - - - - - - - - - - - - - - - - -  .xslt  -->
<!-- embedded stylesheet identical to standalone one, except for
     the <?xml?> declaration which cannot be inserted at the very top of the file
     &eol; entity replaced with $eol variable since !doctype breaks wsf parser -->
<!-- <?xml version='1.0' encoding='iso-8859-1'?> -->
<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
<xsl:output method='text' encoding='iso-8859-1'/>
<xsl:strip-space elements='*'/>
<xsl:variable name='eol' select='"&#xA;"'/>
<xsl:template match='dfxml/fileobject'>
  <xsl:value-of select="concat(hashdigest[@type='MD5'],' &quot;',filename,'&quot;',$eol)"/>
</xsl:template>
</xsl:stylesheet>
</xslt>

<script language="JScript">//<![CDATA[ <!--  - - - - - - - - - - - -   .js  -->
function u32hex(arg)
{ return (arg >>> 0).toString(16).toUpperCase(); }
function xmlErr(err)
{ return "error 0x" + u32hex(err.errorCode) + " (" + err.line + "," + err.linepos + "): " + err.reason; }

var vArgs = WScript.Arguments;
if(vArgs.length < 1 || !vArgs(0).length)
{ WScript.Echo("syntax: dfx2md5.cmd <xmlFile>"); WScript.Quit(1); }
var xmlFile = vArgs(0);
var wsfFile = WScript.ScriptFullName.slice(0, -5); // drop '?.wsf' tail

// ms-recommended msXml6, in-band from xp.sp3 up, except server2k3 requires separate install
var xmlDOMDocProgID = "MSXML2.DOMDocument.6.0";

// load external xml file
var xmlDoc = new ActiveXObject(xmlDOMDocProgID);
xmlDoc.setProperty("NewParser", true);
xmlDoc.validateOnParse = false;
xmlDoc.async = false;
xmlDoc.load(xmlFile);
if(xmlDoc.parseError.errorCode)
{ WScript.Echo("XML " + xmlErr(xmlDoc.parseError)); WScript.Quit(1); }

// load self, then retrieve 'xslt' node at next step
var wsfDoc = new ActiveXObject(xmlDOMDocProgID);
wsfDoc.setProperty("NewParser", true);
wsfDoc.validateOnParse = false;
wsfDoc.async = false;
wsfDoc.load(wsfFile);
if(wsfDoc.parseError.errorCode)
{ WScript.Echo("XSL " + xmlErr(wsfDoc.parseError)); WScript.Quit(1); }

// msXml3 only, override legacy default 'xslPattern'
//wsfDoc.setProperty("SelectionLanguage", 'XPath');
// required in order for 'xpath' to recognize 'xsl' namespace
wsfDoc.setProperty("SelectionNamespaces", "xmlns:xsl='http://www.w3.org/1999/XSL/Transform'");
// could store multiple 'xslt' stylesheets with different 'id' tags, and choose at runtime which one to apply
var xslNode = wsfDoc.documentElement.selectSingleNode("/job/xslt[@id='default']/xsl:stylesheet");

// 'xslDoc' only needed for 'xslPi' otherwise 'xslNode' could be passed to 'transformNode' directly
var xslDoc = new ActiveXObject(xmlDOMDocProgID);
// 'encoding' is parsed and observed, but left out of the 'xslDoc.xml' property
var xmlPi = xslDoc.createProcessingInstruction("xml", "version='1.0' encoding='iso-8859-1' standalone='yes'");
xslDoc.appendChild(xmlPi);
xslDoc.appendChild(xslNode.parentNode.removeChild(xslNode));

// apply transformation, output via stdout.write to avoid extra .echo newline
try
{ WScript.StdOut.Write(xmlDoc.transformNode(xslDoc)); }
catch(err)
{ WScript.Echo("XSLT error 0x" + u32hex(err.number) + ": " + err.description); WScript.Quit(1); }
//]]></script>
</job> <!--  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  -->

To be noted that one would only need to customize the batch and xslt parts in the code above - the script/js block is completely generic.

Liviu

penpen
Expert
Posts: 1991
Joined: 23 Jun 2013 06:15
Location: Germany

Re: js/vbs/html/hta hybrids and chimeras in cmd/bat

#30 Post by penpen » 04 May 2014 06:07

Great idea, to store the xslt(s) into the wsf file, too: I even didn't thought it,
although, up to now, i stored all other (xml) data (== batch scripts/JScripts/VBScripts/... scripts) into it.

penpen

Post Reply