我觉得这个问题非常深入,因为尽管阅读了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 />
元素本身都很小,但我显然必须检查字节缓冲区是否超过一定大小。
答案 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)