是否有适用于 Java 的基于推送/非阻塞的 XML 解析器?

2022-09-03 02:13:31

我正在寻找一个XML解析器,而不是从InputStream或InputSource解析,而是允许将文本块推入解析器。例如,我希望有类似这样的东西:

public class DataReceiver {
    private SAXParser parser = //...
    private DefaultHandler handler = //...

    /**
     * Called each time some data is received.
     */
    public void onDataReceived(byte[] data) {
        parser.push(data, handler);
    }
}

原因是我想要一些可以与NIO网络库很好地配合使用的东西,而不必恢复到支持阻塞输入流所需的每个连接模型的线程。


答案 1

令人惊讶的是,没有人提到一个实现非阻塞(“异步”)解析的Java XML解析器:Aalto。部分原因可能是缺乏文档(以及其低水平的活动)。Aalto实现了基本的Stax API,但也进行了次要扩展以允许推送输入(此部分尚未最终确定;功能存在但API尚未最终确定)。有关更多信息,您可以查看相关的讨论组


答案 2

编辑:现在我明白了。您以块的形式接收 XML,并希望将其馈送到正确的 XML 解析器中。所以你需要一个对象,一端是队列,另一端是输入流?

您可以将收到的字节数组聚合到ByteArrayOutputStream中,将其转换为ByteArrayInputStream并将其馈送到SAXParser。

或者,您可以查看 PipedInputStream/PipedOutputStream 对。在这种情况下,您需要在另一个线程中执行解析,因为 SAX 解析器使用当前线程发出事件,从而阻止您的 receive()。

编辑:根据评论,我建议采取聚合路由。您将块收集到 ByteArrayOutputStream 中。若要了解是否收到了 XML 的所有块,请检查当前块或 ByteArrayOutputStream 的内容是否包含 XML 根节点的结束标记。然后,您可以将数据传递到SAXParser中,该SAXParser现在可以在当前线程中运行而不会出现问题。为了避免不必要的数组重新创建,您可以实现自己的非同步简单字节数组包装器或寻找此类实现。


推荐