【发布时间】:2014-08-20 11:44:46
【问题描述】:
看看这个网站:
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?
【问题讨论】:
-
我没有使用过那些东西,但是查看您的代码,第一个版本使用
PrintStream而不是BufferedOutputStream,而在第二个版本中我看不到BufferedOutputStream。您是否尝试在第二个版本中也使用BufferedOutputStream?您的MyCustomContentHandler看起来可能会有所不同吗? -
添加
BufferedOutputStream并没有帮助,因为它仍然需要FileOutputStream将结果写入文件:transformerHandler.setResult(new StreamResult(new PrintWriter(new BufferedOutputStream(new FileOutputStream(output, true)), true))); -
我可以粘贴自定义处理程序的内容,但我看不出这有什么关系。 1)在大多数情况下,它只是试图成为身份功能。 2)我正在努力摆脱它。
标签: java xml xslt streaming saxon