我试图通过从我的java代码调用XSLT来转换XML。我在将XML字符串作为参数传递给XSLT时遇到了问题。这会导致异常: 从“java.lang.String”到“node-set”的转换无效。
这是调用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);
在搜索了一些解决方案之后,我甚至尝试从param XML字符串创建一个Document对象,并将Document对象传递给setParameter对象。然后我得到了这个例外:
从'com.sun.org.apache.xerces.internal.dom.DeferredDocumentImpl'到'node-set'的转换无效。
处理此输入XML参数的XSLT代码和抛出异常的行:
<xsl:variable name="infoList" select="$paramXML/a/b"/>
我需要作为参数传递的参数XML如下所示:
<?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>
请帮我解决问题。
答案 0 :(得分:1)
这是一个老问题,但我认为它仍然值得回答。
JDK的默认实现使用Xalan-J。早在2005年,issue was raised in Jira against Xalan 2.7就要求支持传递节点或文档对象。在过去的10年中,这个问题还没有得到解决,尽管这些评论表明它很容易做到了。
然而,上述问题表明可以传递DOM树。事实上,以下似乎有效:
String doc = "<root>Hello world!</root>";
transformer.setParameter("mydoc", new StreamSource(new StringReader(doc)));
如果由于某种原因你无法切换到更强大的XSLT处理器,比如Saxon,你也可以考虑另一个relative easy workaround,我引用:
一种解决方法是在您的内部使用文档功能 样式表,其中包含您选择的URI。然后在上面安装
URIResolver
变压器。应该实现URIResolver.resolve
方法来查看 对于该URI并返回DOMSource
,就像您上面描述的那样。
此外,可以覆盖setParameter
方法以使用URIResolver注册节点以使其正交使用。
this answer on SO on the same subject中提供了一些替代解决方法。