[xsl] XSLT in MSXML - removeParameter?

Subject: [xsl] XSLT in MSXML - removeParameter?
From: Scott Trenda <Scott.Trenda@xxxxxxxx>
Date: Tue, 24 Mar 2009 21:33:15 -0500
I'm developing a generic Javascript client-side XSLT library that works across
IE's MSXML-based IXSLProcessor and the W3C XSLTProcessor model in the other
browsers. I'm struggling to find the correct way to remove a previously added
parameter in MSXML, as it seems that they don't provide a straightforward way
of doing so. Here are the methods that the IXSLProcessor provides:

- addObject()
- addParameter()
- reset()
- setStartMode()
- transform()


Now, you'd think that reset() would reset the previously added parameters, but
it does only exactly what it says: "Resets the state of the processor to the
state it was in prior to calling transform." Since you have to add your
parameters using addParameter() before calling transform(), all those
parameters are still added when you call reset(). So all it really does is
clear the output property.

The documentation on addParameter() shows this:

objXSLProcessor.addParameter(baseName, parameter, namespaceURI);
baseName: The name that will be used inside the style sheet to identify the
parameter context.
parameter: In most cases, a number, Boolean, string, IXMLDOMNodeList, or
IXMLDOMNode. Passing in a single node will produce a node list that contains
one node (shortcut). To remove a parameter previously added to the processor,
provide a value of Empty or Null instead. This acts as a signal to the
processor to remove any previously added parameter of the same name.
namespaceURI (optional): An optional namespace.

Now, this looked promising, until I tried it: myProc.addParameter("myParam",
null);
This threw a "Type mismatch" error in IE. The same happened when I tried
myProc.addParameter("myParam"), myProc.addParameter("myParam", undefined) and
myProc.addParameter("myParam", null, ""). I tried
myProc.addParameter("myParam"), but it threw a "Wrong number of arguments or
invalid property assignment" error instead. If I try to remove the parameter
with myProc.addParameter("myParam", ""), then it overwrites the default value
in my stylesheet, like <xsl:param name="myParam" select="'defaultVal'" />.


The googles do (almost) nothing here. Just a bunch of examples of how to add a
single parameter for a single transformation. I came across this (paraphrased)
code that shares my frustration with this limitation:

// HACK: there is no way to remove a parameter from an IE template ... who
writes their APIs?!?
// so just cache the default values here so we can set them all explicitly
when reset() is called
myProc.defaultParams = {};
for (var params = xsltDocObj.selectNodes("/xsl:stylesheet/xsl:param"), i = 0;
i < params.length; i++) {
	myProc.defaultParams[params[i].getAttribute("name")] =
params[i].getAttribute("select");
}

After thinking about it, I don't even think this will work, since I'd have to
parse through the @select content as XPath and try to resolve it into a
default value. Messy and unreliable.


I could create a new processor for each transformation with
myProc.ownerTemplate.createProcessor(). However, I'd *really* like to avoid
doing that for performance reasons, since we're re-using the wrapped processor
object for several transformations.

Has anyone come across this issue before, and how did you deal with it? Is
there really a good, supported, CORRECT way to do this within IXSLProcessor?


~ Scott

(p.s. I know this is a vendor-specific question. If anyone has an idea of a
better place to ask Microsoft about it, I'm all ears.)

Current Thread