Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When using setParameter with a node-set, it raises exception "Invalid conversion from java.lang.String to node-set"

Tags:

java

xml

xslt

I am trying to transform an XML by invoking an XSLT from my java code. I am facing an issue in passing a XML string as parameter to the XSLT. This causes an exception: Invalid conversion from 'java.lang.String' to 'node-set'.

This is the method to invoke the XSLT:

Transformer l_transformer
=TransformerFactory.newInstance().newTransformer(xslt_file_path);
l_transformer.setOutputProperty(OutputKeys.ENCODING, "ISO-8859-1");
l_transformer.setParameter("collateralDoc", param_xmlString);

StringWriter l_writer = new StringWriter();
StringReader l_reader = new StringReader(inputXML);

Source l_in = new StreamSource(l_reader);
Result l_out = new StreamResult(l_writer);

l_transformer.transform(l_in, l_out);

After searching for some solutions I even tried creating a Document object from the param XML string and passed the Document object to the setParameter object. Then I got this exception:

Invalid conversion from 'com.sun.org.apache.xerces.internal.dom.DeferredDocumentImpl' to 'node-set'.

The XSLT code which processes this input XML param and the line which throws the exception: <xsl:variable name="infoList" select="$paramXML/a/b"/>

The param XML which I need to pass as param looks like this:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<a>
    <b>
        <c>
            <d>blah</d>
            <e>blah</e>
        </c>
        <f>
            <g>blah</g>
            <h>blah</h>
        </f>
    </b>
</a>

Please help me in resolving the issue.

like image 992
deepak Avatar asked Nov 01 '22 16:11

deepak


1 Answers

This is an old question, though I think it still deserves an answer.

The default implementation of the JDK uses Xalan-J. Back in 2005, an issue was raised in Jira against Xalan 2.7 for asking to support passing nodes or document objects. In the passed 10 years, this issue has not yet been resolved, even though the comments suggest that it is "easy enough to do".

The above issue suggests, however, that it is possible to pass a DOM Tree. In fact, the following appears to work:

String doc = "<root>Hello world!</root>";
transformer.setParameter("mydoc", new StreamSource(new StringReader(doc)));

If for some reason you cannot switch to a more capable XSLT processor, like Saxon, you may also consider another relative easy workaround, I quote:

One workaround would be to use the document function inside your stylesheet with a URI of your choosing. Then install a URIResolver on the Transformer. The URIResolver.resolve method should be implemented to look for that URI and return a DOMSource like the one you've described above.

In addition, one could override the setParameter method to register a Node with your URIResolver to make its use orthogonal.

A few alternative workarounds have been given in this answer on SO on the same subject.

like image 176
Abel Avatar answered Nov 15 '22 06:11

Abel