看一下这个网站:
http://xmpp.wordpress.com:8008/firehose.xml?type=text/plain
它不断传输数据。您可以使用最新版本的XSLT(v3)使用以下命令转换此内容:
<xsl:stream href="http://xmpp.wordpress.com:8008/firehose.xml?type=text/plain">
如果我想编写一些Java代码来启动转换(使用已实现xsl:stream的Saxon),我可以这样做:
// XSL
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer(new StreamSource(new FileInputStream(xslFile)));
// XML
StreamSource xmlSource = new StreamSource(new FileInputStream(xmlFile));
// Output
MyCustomContentHandler handler = new MyCustomContentHandler();
PrintStream outputPrintStream = new PrintStream(new BufferedOutputStream(new FileOutputStream(outputFile)), true);
handler.setPrintStream(outputPrintStream);
Result result = new SAXResult(handler);
// Transform
transformer.transform(xmlSource, result);
这很有效。如果让它运行一段时间,然后打开输出文件,你会看到它中的数据。如果稍后重新打开它,您将看到更多数据。关键是处理各种SAX事件的自定义内容处理程序。
但是假设我真的不想要自定义内容处理程序。假设我只想保持XSLT的输出。我可以像这样修改我的代码:
// XSL
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer(new StreamSource(new FileInputStream(xslFile)));
// XML
StreamSource xmlSource = new StreamSource(new FileInputStream(xmlFile));
// Output
TransformerHandler transformerHandler = ((SAXTransformerFactory) SAXTransformerFactory.newInstance()).newTransformerHandler();
transformerHandler.setResult(new StreamResult(new PrintWriter(new FileOutputStream(outputFile, true), true)));
// or this…
//transformerHandler.setResult(new StreamResult(new FileOutputStream(outputFile)));
// or this…
//transformerHandler.setResult(new StreamResult(new FileWriter(outputFile)));
ContentHandler contentHandler = (ContentHandler) transformerHandler;
SAXResult result = new SAXResult(transformerHandler);
// Transform
transformer.transform(xmlSource, result);
好消息是我不再需要自定义内容处理程序,我的输出现在完全匹配XSLT的输出。坏消息是,尽管此代码适用于非流式XSLT,但它不适用于流式XSLT。尽管我尝试设置结果(参见上面的“或者......”语句),但没有任何内容写入文件。我怀疑某种缓冲问题。
问题:如何将这两者中的最佳组合在一起?如何在不使用自定义内容处理程序的情况下转换流式XSLT?
答案 0 :(得分:1)
这似乎是6月份saxon-help列表中一个线程的重新运行:
http://sourceforge.net/p/saxon/mailman/message/32472658/
结论是输出以某种方式在输出流管道中缓冲。 Saxon正在发出表示转换结果的事件,正如您提供的ContentHandler所示,但这些事件的序列化正在I / O系统中缓冲。
答案 1 :(得分:0)
此时,似乎无法做我想做的事情。我目前的解决方案是使用自定义内容处理程序(根据我上面的问题)并通过标准的XSLT身份转换运行其结果。有点丑陋,效率不高,但它确实有效。