Bug 14101 - XSLTProcessor does not accept Nodes as parameter values
Summary: XSLTProcessor does not accept Nodes as parameter values
Status: NEW
Alias: None
Product: WebKit
Classification: Unclassified
Component: XML (show other bugs)
Version: 523.x (Safari 3)
Hardware: All All
: P2 Normal
Assignee: Nobody
URL:
Keywords: InRadar
: 20444 (view as bug list)
Depends on:
Blocks:
 
Reported: 2007-06-12 12:42 PDT by Sjoerd Visscher
Modified: 2019-01-25 12:02 PST (History)
16 users (show)

See Also:


Attachments
Should render Hello World! when this bug is fixed. (1.14 KB, text/html)
2008-03-07 03:56 PST, Robbert Broersma
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Sjoerd Visscher 2007-06-12 12:42:47 PDT
F.e. assuming doc is the XML document <test/>:

proc.setParameter(null, "test", doc)

With XSLT:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

  <xsl:param name="test"/>
  
  <xsl:template match="/">
    <result>
      <xsl:copy-of select="$test" />
    </result>
  </xsl:tempate>

</xsl:stylesheet>

gives:

<result>[object Document]</result>

where I expected:

<result><test/></result>
Comment 1 Alexey Proskuryakov 2007-06-13 13:18:28 PDT
Confirmed, it's an nsIVariant in Gecko, but a String in WebKit.
Comment 2 Alexey Proskuryakov 2007-06-29 09:02:02 PDT
What types does Firefox accept in setParameter()?

If I understand the spec correctly, XSLT parameters are just expressions, so the type can be one of boolean, number, string, or node-set. Is there a way to pass an arbitrary node-set, rather than a single Node? Also, can XPathEvaluator result values be used in XSLTProcessor?
Comment 3 Robbert Broersma 2008-03-07 03:56:30 PST
Created attachment 19582 [details]
Should render Hello World! when this bug is fixed.

I would very much appreciate if this bug is being fixed.

I have attached a test file that will render "Hello World!" when this bug is fixed. Opera and Firefox already succeed, but Safari returns "Hello[object Element]".
Comment 4 Robbert Broersma 2008-03-07 09:22:00 PST
Bug filed in libxslt for this:
http://bugzilla.gnome.org/show_bug.cgi?id=521030
Comment 5 toby schachman 2008-03-24 19:24:24 PDT
(In reply to comment #2)
> What types does Firefox accept in setParameter()?
> 
> If I understand the spec correctly, XSLT parameters are just expressions, so
> the type can be one of boolean, number, string, or node-set. Is there a way to
> pass an arbitrary node-set, rather than a single Node? Also, can XPathEvaluator
> result values be used in XSLTProcessor?
> 

In Firefox, one can pass a node-set by setting the parameter to an array of nodes. There may be other ways, I found this out by trial and error.

One more vote here to resolve this bug (at least for single nodes). It's keeping me from porting my app to Webkit.
Comment 6 Dave Hyatt 2008-03-24 19:33:18 PDT
Not sure what we can really do here if it's a bug in libxslt.

Comment 7 Alexey Proskuryakov 2008-03-28 02:09:46 PDT
From the WebKit side, the main issue AFAICT is that it's hard to properly pass a node reference from DOM to libxml2, given that we re-create the document each time for XSLT processing.
Comment 8 Sjoerd Visscher 2008-03-28 06:20:10 PDT
That is a really limiting way to implement XSLT. If you'd want to implement user defined extension functions, which you can do with MSXML, you would have to be able to get the original node back for nodes that are passed to such functions.
Comment 9 Alexey Proskuryakov 2008-08-19 04:58:19 PDT
*** Bug 20444 has been marked as a duplicate of this bug. ***
Comment 10 Jason.Shang 2008-08-19 23:26:13 PDT
(In reply to comment #9)
> *** Bug 20444 has been marked as a duplicate of this bug. ***

Could you tell me that when the bug could be fixed? Thanks!

more detail:
The following code: 
alert(typeof(proc.getParameter(null,"test")));
will display "string".
It sounds as if Safari converts the DOM document node to a string([object Document]) and passes that string into xsl.
Comment 11 Charles Fulnecky 2009-07-07 07:01:59 PDT
The ability to pass a node-set as a parameter is a critical component for high-performance push/comet  style applications that use XML as an in memory database.  

XSLT provides a performant means of merging an incoming document with an existing client-side model. Javascripted DOM operations are relatively costly for large documents (in excess of 2 megabytes).

Without the ability to pass a node-set we are limited to using URLs which prevents pre-processing and error handling by standard AJAX XMLHttp libraries.

See http://www2.informatik.hu-berlin.de/~obecker/XSLT/#merge
Comment 12 Deirdre Saoirse Moen 2010-02-22 14:54:11 PST
<rdar://problem/7672261>
Comment 13 Charles Fulnecky 2010-03-26 05:42:12 PDT
The passing of nodes as parameter values is fully supported in the latest versions of:
Internet Explorer
Firefox
Opera
Comment 14 Rick Brandt 2010-09-28 09:08:52 PDT
Still seeing this over three years later.  As a platform for web-applications this is a pretty big limitation of the web-kit browsers.
Comment 15 Michael Slama 2012-01-19 09:56:52 PST
(In reply to comment #13)
> The passing of nodes as parameter values is fully supported in the latest versions of:
> Internet Explorer
> Firefox
> Opera

We (HP ESSN) are being asked to add support for Chrome in upcoming enterprise Web application releases due to Chrome's rise in adoption, and this limitation is preventing that for some of our teams. 

We have been successfully using IE and Firefox to pass node-sets as parameters since late 2005 when the good folks at Mozilla (esp. Peter Van Der Beken) fixed their XSLT library to support node-set parameters in version 1.50. See https://bugzilla.mozilla.org/show_bug.cgi?id=248025 (comment #15 is referring to me because I was building Mozilla to test the fix).

Is there a way to move this issue to a higher priority, or perhaps request outside help to get it addressed? This is a critical requirement for our XSLT-heavy Web applications because we need to pass entire documents to the XSLT processor as parameters.

We have a large customer base and the addition of Chrome support within our organization would boost adoption even further IMO.
Comment 16 William J. Edney 2014-08-27 06:57:25 PDT
7 years... wow.

Unfortunately, it looks like this will never get fixed. And with the Blink fork, that makes it even more unlikely that it will be fixed for both codebases, etc.

I have a relatively painless workaround for this bug if anyone is interested: Use JavaScript to grab the 'xsl:param' elements in your XSLT document, replace them with 'xsl:variable' elements with your 'node' content for that parameter as child content and then use that modified XSLT document in the processor.

If folks are still interested enough to want a code snippet, I can paste that here.

Cheers,

- Bill
Comment 17 Mike 2019-01-25 09:20:16 PST
Bill

I know it is a long shot at this point (given it is almost 5 years later from the last comment) but I would be interested in the javascript snippet you put together.  I'm working on an old legacy product and am actively looking for a workaround to this issue to expand browser support.  

Thanks Mike.
Comment 18 William J. Edney 2019-01-25 11:39:09 PST
Mike -

The codebase I was working from 5 years ago has changed, but I found a chunk of code in a temp file that looked to be more-or-less working code (but probably should just be treated as pseudo-code - I'm sure you'll have to debug a bit):

Assume you have an Array of Objects that contain the parameters you want to feed to the sheet:

params = [
    {name: 'foo', value: <Node>},
    {name: 'bar', value: <Node>),
    ...
];


Assume that 'xsltDoc' is the *XSLT* document that you're using to process the source document and 'inputDoc' is the source XML that you're transforming.

for (i = 0; i < params.length; i++) {

    // Search the style doc to see if there's an 'xsl:param' element with a name matching params[i].name
    paramElem = xsltDoc.evaluate('//param[@name="' + params[i].name '"]', null, XPathResult.ANY_TYPE, null);

    if (paramElem) {

        // Create an 'xsl:variable' element and set it's name to be the same as the 'xsl:param'
        newElem = xsltDoc.createElementNS('http://www.w3.org/1999/XSL/Transform', 'variable');
        newElem.setAttribute('name', params[i].name);

        // Swap in the 'xsl:variable' element for the 'xsl:param' element
        paramElem.parentNode.replaceChild(newElem, paramElem);

        // Append the parameter node under the 'xsl:variable' element
        newElem.appendChild(params[i].value);
    }
}

That's about it. Go ahead and import the sheet:

processor = new XSLTProcessor();
processor.importStylesheet(xsltDoc);

And then run it through the processor:

resultDoc = processor.transformToDocument(inputDoc);

Note that this approach has the distinct disadvantage of modifying your *XSLT* document. If you need to do multiple transformations, you'll want to clone the XSLT document and keep a pristine copying before modifying it like this.

I would caution again that the code above is close, but probably has bugs. Sorry I don't have the original running source to give you.

If you run into issues, feel free to email me directly. My email address is: bedney@technicalpursuit.com

Hope this helps!

Cheers,

- Bill
Comment 19 Mike 2019-01-25 11:51:33 PST
Cheers! This is a huge help and I will treat as psuedo-code. I will only bother you if I run into issues I can not work around.
Comment 20 William J. Edney 2019-01-25 12:02:31 PST
Mike -

In looking back over this code, I realized that the call to xsltDoc.evaluate() is going to give you back an 'XPathResult' object - not the element itself.

More docs can be found here: https://developer.mozilla.org/en-US/docs/Web/API/XPathResult

It was all so long ago... ;-) And the API around 'document.evaluate' is pretty weird.

I think what you'll want is the '.singleNodeValue' of the result.

Sorry in advance to everyone on this bug for the not-quite-interactive debugging session ;-).

Cheers,

- Bill