views:

804

answers:

2

I'm trying to have a script automatically transform an xml file into several html files using different xslt style sheets. However, whatever I try, I get errors. I've tried it in both VBscript and JScript, and both give me errors. The xml file is 537 KB, and the xsl file is 5 KB.

Here's iteration 1 in JScript. This script works for one of my style sheets (a style sheet that creates a smaller html file), but on a stylesheet that creates a bigger html file, it gives me an "invalid procedure call or argument" on outstr (as if outstr didn't return properly) error :

var xsl = new ActiveXObject("MSXML2.DomDocument.6.0");
xsl.async = false;
var boolval = xsl.load("../Commands/commands.xsl");
if(!boolval)
{
    WScript.Echo("XSL load error");
    WScript.Quit();
}
var xml = new ActiveXObject("MSXML2.DomDocument.6.0");
xml.async = false;
boolval = xml.load("../Commands/commands.xml")
if(!boolval)
{
    WScript.Echo ("XML load error " );
    WScript.Quit();
}

var fso = new ActiveXObject("Scripting.FileSystemObject");
var outstr = xml.transformNode(xsl);

var ofl = fso.CreateTextFile("../Commands/commands.html", true, false);
ofl.Write (outstr);
ofl.Close();

So here's iteration 2, using the transformNodeToObject method instead. In this case, I get an "Unspecified error" code 80004005 in msxml6.dll:

var xsl = new ActiveXObject("MSXML2.DomDocument.6.0");
xsl.async = false;
var boolval = xsl.load("../Commands/commands.xsl");
if(!boolval)
{
    WScript.Echo("XSL load error");
    WScript.Quit();
}
var xml = new ActiveXObject("MSXML2.DomDocument.6.0");
xml.async = false;
boolval = xml.load("../Commands/commands.xml")
if(!boolval)
{
    WScript.Echo ("XML load error " );
    WScript.Quit();
}

var result = new ActiveXObject("MSXML2.DomDocument.6.0");
xml.transformNodeToObject(xsl, result);

result.save("../Commands/commands.html");

My intuition says that the processor just can't handle creating a file that big. Is this right, or am I doing something wrong. If it's just a size issue, is there some other library/object I can use in vbscript/jscript that will get the job done?

+2  A: 

A few kB of XML won't break MSXML, under no circumstances whatsoever. The memory of your machine is the limit, so file size can't be the problem. Also the choice of host language (JScript or VBScript) is completely irrelevant, there is nothing that VBScript can do but JScript can't, or vice-versa. You are doing COM here, so the language can't be the problem either. It's safe to stop looking into that direction.

This leaves one possibility. You must be doing something wrong. ;-) This may include MSXML configuration or installation problems on your machine, maybe even wrong file system access settings or process credentials.

Since I cannot spot an immediate problem in your code and you did not provide any XML to test with, I can only recommend a few things that may help debugging this. Try, not necessarily in that order:

  • Check that all your XML files are well-formed and correctly encoded. I am sure you are through with that already. Loading them into IE will suffice, if that works they're good.
  • Remove and re-install MSXML, make sure you also have an older version (4.0) installed.
  • Download msxsl.exe from Microsoft and do the transformations on the command line, to check if they work at all - this tiny tool uses MSXML internally and has never failed me in the past.
  • Try your code with "MSXML2.DomDocument.4.0", as there is no strikingly good reason to use 6.0 anyway (other than "newer is better", I guess).
  • Only to exclude it as a reason, run the whole thing as an Admin level user, and on a different machine. See if the error is reproducible.
  • If all else fails, upload the files somewhere, post the links here and I'll have a look at them as well.

Hope this helps.

Tomalak
Tomalak,Thanks for the help. I tried all of the above. xml/xsl was well-formed. Install/re-install made no difference. I was able to reproduce it on a different machine. 4.0 gave basically the same results (although on iteration 2 it gave no errors but produced an empty html file). msxsl.exe worked great, so that may be the solution to use, although it's frustrating that I can't get it to work with scripting. I've uploaded the files to http://www.obryantfamilytree.com/TestXSL.zip, mostly for curiosity's sake, since the msxsl.exe solution works, so if you're so inclined...Thanks again.
Anthony Johnson
The error is - you can't use "TransformNodeToObject" and "<xsl:output method="html" />" together. Change it to "<xsl:output method="xml" />" and it will work. (Hint: "TransformNodeToObject" tries to save the output into an XML DOM.)
Tomalak
Beyond that I think it is generally recommendable to save the transformation result via a DOMDocument.save(). Using a string and a TextStream object can mess up the coherence between declared and actual encoding.
Tomalak
Your first code sample (CreateTextFile) will work if you declare the FileStream object as Unicode. Simply set the third argument of CreateTextFile() to True). But as I said, I'd recommend against that approach. Related reading: http://support.microsoft.com/kb/275883
Tomalak
A few remarks to your transformation: Consider using CSS classes for all those small templates at the end. All this redundant CSS style info inflates the result document hugely. You can merge equal templates by using the XPath union operator, e.g. <xsl:template match="code | pre">. Wrap literal text (like the " "s) into <xsl:text> nodes to separate XSL code and XSL formatting whitespace. This is beneficial for the format of the output. Oh, and using the same ID twice is illegal in HTML and XML (i.e. "<a id="link">).
Tomalak
Tomalak,Thanks, that's a great help. I'll make those changes.
Anthony Johnson
A: 

I have the same problem in a similar situation. I use a xsl stylesheet that produces complex (not so big) xml from about 8MB xml data. The size of the resulting xml seems to matter. If I limit the result size in xsl (e.g by using xxx[position()<500]) it does not produce an error.

This happens in two different computer using msxml6.0. The progid does not change the result (domdocument3,4,5,6 or freethreaded). I have not tried installing an older parser.

Does anyone have any simple ideas how to solve this? Upgrade to Java or .NET are my best guesses. Do you have any solution that requires less work... ;-)

AXml