5

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.

Abel
  • 56,041
  • 24
  • 146
  • 247
deepak
  • 339
  • 6
  • 16
  • Which XSLT processor do you use? You could check its documentation and parse the string with XML into a tree representation the XSLT processor know to process. Unfortunately http://xalan.apache.org/old/xalan-j/apidocs/javax/xml/transform/Transformer.html#setParameter%28java.lang.String,%20java.lang.Object%29 does not say more than "The value object. This can be any valid Java object. It is up to the processor to provide the proper object coersion". – Martin Honnen Aug 20 '13 at 09:36
  • Hey Martin, I am using the default transformer that comes with JDK 5. – deepak Aug 20 '13 at 13:28
  • I think JDK uses an internal version of Xalan, I am not familiar with the types of parameters it accepts. – Martin Honnen Aug 21 '13 at 16:34
  • 1
    Fixed it using XSLT 2.0 implementation (SAXON). Thank you everyone for the inputs. – deepak Aug 29 '13 at 21:03

1 Answers1

2

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.

Community
  • 1
  • 1
Abel
  • 56,041
  • 24
  • 146
  • 247