Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是否有基于推送/非阻塞的Java XML解析器?_Java_Xml_Nonblocking - Fatal编程技术网

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

是否有基于推送/非阻塞的Java XML解析器?,java,xml,nonblocking,Java,Xml,Nonblocking,我正在寻找一个XML解析器,它不是从InputStream或InputSource解析,而是允许将文本块推送到解析器中。例如,我想要以下的东西: public class DataReceiver { private SAXParser parser = //... private DefaultHandler handler = //... /** * Called each time some data is received. */ p

我正在寻找一个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网络库能够发挥良好的作用,而不是必须恢复到支持阻塞输入流所需的每个连接模型的线程。

编辑:现在我明白了。您以块的形式接收XML,并希望将其提供给适当的XML解析器。所以您需要一个对象,一端是队列,另一端是InputStream

您可以将接收到的字节数组聚合到ByteArrayInputStream中,将其转换为ByteArrayInputStream并将其提供给SAXParser

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

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

这是Xerces J-Users邮件列表中的一篇(2009年4月)文章,其中原始海报存在完全相同的问题。“Jeff”给出了一个可能非常好的回复,但没有跟进原始海报的回复:

它可能足够新,可以在列表中出现,或者至少有助于搜索

编辑

找到了另一个有用的链接,提到了一个名为Woodstox的库,描述了流与基于NIO的解析器的状态,以及一些模拟流的可能方法:


对不起,我没能解决这个问题。 我找不到像我需要的那样的解析器。 但我想自己写一本。 一个非常简单的问题:就像可行性研究一样,但足以解决我的问题,也足以解决你的问题。 我一直都很胖,接下来的两周我会出去, 但也许在七月份我会开始工作。 我一有工作就告诉你


mt

检查XMLLeightweightParser,以及由于NIO,它如何从单个块生成XML消息。整个项目都是关于NIO和XMPP问题答案的好来源。

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

添加另一个答案,因为这个问题对于相关的谷歌搜索来说仍然很重要-0.9.7(2011年3月)具有异步XML编程功能。这允许您传递任意大小的文档块以继续解析,并且新的StaX事件类型
event_complete
指示输入缓冲区已用尽且文档仍不完整

这是(作者)的例子:

byte[]msg=“非常简单的输入文档!”.getBytes();
AsyncXMLStreamReader asyncReader=新建InputFactoryImpl()。CreateAyncXmlStreamReader();
final AsyncInputFeeder=asyncReader.getInputFeeder();
int inputPtr=0;//我们一次输入一个字节
int类型=0;
做{
//可能需要馈送多个“段”
而((type=asyncReader.next())==AsyncXMLStreamReader.EVENT_不完整){
feeder.feedInput(msg,inputPtr++,1);
if(inputPtr>=msg.length){//表示内容结束(对于错误处理很重要)
feeder.endOfInput();
}
}
//一旦我们有了完整的事件,我们只需转储事件类型(目前)
System.out.println(“获取类型为:+类型的事件”);
//也可以使用Stax按原样复制事件,或执行任何其他正常的非阻塞处理:
//xmlStreamWriter.copyEventFromReader(asyncReader,false);
}while(type!=AsyncXMLStreamReader.END_文档);

NioSax与ByteBuffers一起工作

我能找到的最新版本(2010年10.6版)的源代码在 Sonatype Maven存储库:


了解XML文档的长度很有意思。我没有任何XML文档,我正在考虑实现一个XMPP服务器,因此我正在寻找与NIO网络库配合良好的东西。看看用Java编写的开源XMPP服务器,看看它们是如何解决问题的,这可能是一个好主意。Tigase和OpenFire是我想到的第一批候选人。唉,我也有同样的问题。这就是为什么所有运行时都应该有
调用cc
。然后,我们可以通过实现
InputStream
来实现这一点。PipedInputStream/PipedOutStream看起来是一种为传统解析器提供InputStream和push-in块的好方法。这种方法仍然需要每个客户端连接一个线程,它只是将问题转移到代码的不同区域。如果我采用每连接一个线程的模式,那么我可能只会使用传统的套接字和InputStreams,因为解决方案会更简单。我从来没有听说过Java解析器具有您正在寻找的功能。我想如果没有C#yield-return结构的等价物(例如停止解析并返回给调用者以及随后的conti)的管理,实现一个函数是非常困难的
     byte[] msg = "<html>Very <b>simple</b> input document!</html>".getBytes();
      AsyncXMLStreamReader asyncReader = new InputFactoryImpl().createAsyncXMLStreamReader();
      final AsyncInputFeeder feeder = asyncReader.getInputFeeder();
      int inputPtr = 0; // as we feed byte at a time
      int type = 0;

      do {
        // May need to feed multiple "segments"
        while ((type = asyncReader.next()) == AsyncXMLStreamReader.EVENT_INCOMPLETE) {
          feeder.feedInput(msg, inputPtr++, 1);
          if (inputPtr >= msg.length) { // to indicate end-of-content (important for error handling)
            feeder.endOfInput();
          }
        }
        // and once we have full event, we just dump out event type (for now)
        System.out.println("Got event of type: "+type);
        // could also just copy event as is, using Stax, or do any other normal non-blocking handling:
        // xmlStreamWriter.copyEventFromReader(asyncReader, false);
      } while (type != AsyncXMLStreamReader.END_DOCUMENT);