简体   繁体   English

在没有自定义内容处理程序的情况下转换流式 XSLT

[英]Transforming Streaming XSLT Without a Custom Content Handler

Take a look at this website:看看这个网站:

http://xmpp.wordpress.com:8008/firehose.xml?type=text/plain http://xmpp.wordpress.com:8008/firehose.xml?type=text/plain

It constantly streams data.它不断地传输数据。 You can transform this content using the newest version of XSLT (v3), with a command like this:您可以使用最新版本的 XSLT (v3) 转换此内容,命令如下:

<xsl:stream href="http://xmpp.wordpress.com:8008/firehose.xml?type=text/plain">

If I want to write some Java code to initiate the transformation (using Saxon, which has implemented xsl:stream), I can do this:如果我想编写一些 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);

This works.这有效。 If you let it run for a bit, then open the output file, you'll see data in it.如果让它运行一会儿,然后打开输出文件,您将看到其中的数据。 If you re-open it a bit later, you'll see even more data.如果稍后重新打开它,您将看到更多数据。 The key to this is the custom content handler that processes the various SAX events.其关键是处理各种 SAX 事件的自定义内容处理程序。

But suppose that I don't really want a custom content handler.但是假设我真的不需要自定义内容处理程序。 Suppose I just want to keep the output of the XSLT as is.假设我只想保持 XSLT 的输出不变。 I can modify my code like this:我可以像这样修改我的代码:

// 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);

The good news is that I no longer need a custom content handler, and my output now matches the output of the XSLT exactly.好消息是我不再需要自定义内容处理程序,而且我的输出现在与 XSLT 的输出完全匹配。 The bad news is that although this code works with non-streaming XSLT, it does not work with streaming XSLT.坏消息是,尽管此代码适用于非流式 XSLT,但它不适用于流式 XSLT。 Despite my various attempts at setting the result (see the “or this…” statements above), nothing is written to the file.尽管我多次尝试设置结果(参见上面的“或这个……”语句),但没有任何内容写入文件。 I suspect there's a buffering problem of some sort.我怀疑存在某种缓冲问题。

Question: How can I combine the best of these two together?问题:我怎样才能将这两者的优点结合在一起? How can I transform a streaming XSLT without having to use a custom content handler?如何在不使用自定义内容处理程序的情况下转换流式 XSLT?

This seems to be a rerun of a thread on the saxon-help list in June:这似乎是 6 月份撒克逊人帮助列表上一个线程的重播:

http://sourceforge.net/p/saxon/mailman/message/32472658/ http://sourceforge.net/p/saxon/mailman/message/32472658/

The conclusion there was that the output was somehow being buffered in the output stream pipeline.结论是输出以某种方式被缓冲在输出流管道中。 Saxon is emitting events representing the transformation result, as you see by supplying a ContentHandler, but the serialization of these events is being buffered in the I/O system.正如您通过提供 ContentHandler 看到的那样,Saxon 正在发出表示转换结果的事件,但这些事件的序列化正在 I/O 系统中进行缓冲。

At this time, it does not appear to be possible to do what I want to do.这个时候,我想做的事情似乎也做不到。 My current solution is to use a custom content handler (per my question above) and run its results through a standard XSLT identity transformation.我当前的解决方案是使用自定义内容处理程序(根据我上面的问题)并通过标准 XSLT 身份转换运行其结果。 A bit ugly and not very efficient, but it works.有点难看而且效率不高,但它有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM