将xml节点/文档/片段作为参数传递给xslt

我试图将w3c.dom.DocumentElementNodeList作为参数传递给xslt转换。

我希望能够在xslt中处理它:

         

我将参数传递为:

  Document params = createLinksParams(links); transformer.setParameter("links", params); 

我得到这个例外:

‘从’com.sun.org.apache.xerces.internal.dom.DocumentImpl’到’node-set’的转换无效。’

我也尝试了exslt:node-set()xalan:nodeset()等,但它不起作用。

似乎内部xalan除了他自己的Node实现。

如何在不引发此问题的情况下做类似的事情?

我不能使用document($param)因为我在运行中构建了doc。

(发布一个新的答案,因为前一个没有解决问题,这个新的答案与以前完全不同)

似乎是XALAN编译处理器的已知问题( XALANJ-2057 , 如何将节点作为参数传递给XSLTC处理器的translet )。

那么,有哪些替代方案呢?

  1. 如我在如何将节点作为参数传递给XSLTC处理器post的translet中所概述的那样乱用URI
  2. 而不是XALAN编译处理器(XSLTC), 使用XALAN解释处理器 。 或支持此类行为的任何其他XSLT处理器。
  3. 使用DTMAxisIterator ,也可以在响应中概述如何将节点作为参数传递给XSLTC处理器后的translet – 但不确定它是否可行。
  4. 创建一个新的DOM树 ,将“参数”DOM与原始XSLT输入文档组合在一起

我找到了一个解决方案(这里: XSLT Processing with Java:在参数中传递xml内容 ),它也适用于你的情况:

 String urls = "https://www.google.com..."; trans.setParameter("lookupdoc", new StreamSource(new StringReader(urls))); 

而不是从字符串创建一个uriresolver,只需从字符串阅读器创建一个流源并将其传递给样式表。

之后,我能够正常访问doc作为XML:

  ...  

没有用xalan测试,但也许答案会帮助那些偶然发现这个问题的人:)

如果查看Document JavaDoc ,可以看到它扩展了Node接口,但没有扩展NodeList 。 不确定它是否可行,但您可以尝试传入params.getChildNodes()而不是params

以下是URIResolver Gambit的一个工作示例,解决方案列表中的#1:

 import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.URIResolver; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import java.io.StringReader; import java.io.StringWriter; public class XSLTest { public static void main(String[] args) { class MyResolver implements URIResolver { String _xml; MyResolver(String xml) { _xml = xml; } @Override public Source resolve(String href, String base) throws TransformerException { return new StreamSource(new StringReader(_xml)); } } String lookup = "\n" + "\n" + " https://www.google.com\n" + " https://www.yahoo.com\n" + " https://www.apple.com\n" + ""; String main = "" + ""+ " Yahoo"+ " Google"+ ""; String xsl = "\n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + ""; try { // xsl doc Source xsltSource = new StreamSource(new StringReader(xsl)); TransformerFactory transFact = TransformerFactory.newInstance(); Transformer trans = transFact.newTransformer(xsltSource); // main doc Source mainSource = new StreamSource(new StringReader(main)); // lookup doc - stage it in the URI resolver trans.setURIResolver(new MyResolver(lookup)); // dummy URL, you could use different values here to // support multiple document parameters trans.setParameter("lookup-doc", "xml://lookup"); StringWriter out = new StringWriter(); trans.transform(mainSource, new StreamResult(out)); System.out.println(out.toString()); } catch (TransformerException e) { System.err.println("It's the wrong trousers Gromit, and they've gone wrong!"); e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } } } 

我也有一个工作版本,我把xml源放在 URI中

 xml://https://www.google.com... 

但我认为这可能会在某个地方遇到长度限制。