5

尽管阅读了官方文档和这些问题中链接的资源,但我觉得问这个问题有点离题了:

如何理解 play2 中的“Iteratee”?

Play 2.0中看不懂Iteratee、Enumerator、Enumeratee

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

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

任何人都可以提供任何指导和/或示例来说明如何实现这一点吗?

更新:更多背景:-

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

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

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

这将如何与 Play BodyParser 一起工作,我不完全确定。如果我能进一步澄清我想要做什么,则会有更多更新!

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

4

3 回答 3

3

扫描文档,它似乎只是收集了这些信息,并为 Java 提供了一个完整的 org.w3c.Document ,为 scala 提供了一个 scala.xml : play xml requests

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

不幸的是,当前可用的(和已知的)xml 库都不支持按照 Iteratee 模型提供块。 Scales Xml提供了一种处理流中的块的方法(将拉解析器转换为枚举器) - 请参见此处的示例。

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

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

于 2012-07-15T13:52:33.997 回答
1

这篇文章描述了您的问题的解决方案http://petersiemen.net/parsing-large-xml-streams-with-enumerators-iteratees-and-enumeratees/

于 2015-03-09T16:26:06.567 回答
1

基于 XOM的Nux解析器将接受分块输入,并且专为流式传输大型 XML 文件而设计。这听起来正是你想要的。

于 2012-10-30T00:53:45.310 回答