Play Framework 2.0 BodyParser - 推送解析XML流

时间:2012-07-14 19:00:18

标签: scala xml-parsing streaming playframework-2.0 iterate

我觉得这个问题非常深入,因为尽管阅读了official docs以及这些问题中链接的资源:

How to understand `Iteratee` in play2?

Can't understand Iteratee, Enumerator, Enumeratee in Play 2.0

......我对迭代器,枚举器和Play 2.0的反应模型一般都很朦胧。但无论如何,我想建立一个Web服务,允许我上传大型XML(> 100MB)文件,挑选某些特定的(非交错的)NodeSeq,处理它们,并将结果流回客户端。

我认为我需要做的第一件事就是编写一个BodyParser,它接收大块的字节,将它们提供给XML解析器,然后以懒惰的方式发出我想要的NodeSeq流,比如<doc>...</doc>

是否有人可以提供任何指导和/或示例来说明如何实现这一目标?

更新:更多背景: -

我的XML实际上是一个Solr add文档,所以它看起来像:

<add>
    <doc>
        <field name="name">Some Entity</field>
        <field name="details">Blah blah...</field>
        ...
    </doc>
    ...
</add>

我想以流式方式处理每个<doc>,所以我的解析器显然必须等到它达到<doc>启动事件,缓冲所有内容直到等效的</doc>结束事件,并发出已完成元素的NodeSeq,然后刷新其缓冲区。

如何使用Play BodyParser,我不完全确定。如果我可以进一步澄清我想做的事情,可以获得更多更新!

尽管整个XML文件很大,但每个<doc />元素本身都很小,但我显然必须检查字节缓冲区是否超过一定大小。

3 个答案:

答案 0 :(得分:3)

扫描文档似乎只是收集此信息并为Java提供整个org.w3c.Document,为scala提供scala.xml:play xml requests

这似乎不太可能对你的情况有所帮助,因为你最终会得到一个大内存模型。对于100MB的xml,您可以期望解析任何高达700MB的使用量。

不幸的是,根据Iteratee模型,当前可用的(和已知的)xml库都不支持以块的形式提供数据。 Scales Xml提供了一种从流处理块的方法(将拉解析器转换为枚举器) - 有关示例,请参阅here

因此,目前我建议使用普通的InputStream(或Reader)并将其输入类似于Scales的东西。也许Play专家可以推荐如何从框架内检索流(不完全处理它)。

注意:当前的决赛即将结束,但下一个主要版本(0.5)将尝试利用aalto-xml来允许双方进行部分流处理(非阻塞)。

答案 1 :(得分:1)

基于XOM的Nux解析器将接受分块输入,专门用于流式传输大型XML文件。这听起来就像你想要的那样。

答案 2 :(得分:1)