2012-07-14 33 views
5

me siento más bien fuera de mi hacer esta pregunta, ya que a pesar de leer el official docs y los recursos vinculados en estas preguntas:Juega BodyParser Framework 2.0 - empuje analizar XML arroyos

How to understand `Iteratee` in play2?

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

... Todavía soy bastante confuso sobre iteratees, enumeradores y el modelo reactivo de Play 2.0 en general. Pero de todos modos, me gustaría configurar un servicio web que me permita cargar archivos XML grandes (> 100MB), seleccionar ciertos NodeSeq específicos (no intercalados), procesarlos y transmitir los resultados al cliente.

Creo que lo primero que tengo que hacer es escribir un BodyParser que tome trozos de bytes, los introduzca en un analizador XML y emita un flujo de los NodeSeqs que deseo, digamos <doc>...</doc>, de manera perezosa.

¿Alguien podría ofrecer alguna guía y/o ejemplos que ilustren cómo se podría lograr esto?

Actualización: Más de fondo: -

Mi XML es en realidad un documento Solr add, por lo que parece:

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

Quiero procesar cada <doc> de manera streaming, por lo que mi parser obviamente tiene que esperar hasta que llegue a un evento de inicio <doc>, almacenar todo hasta el evento final equivalente </doc>, y emitir un NodeSeq del elemento completado, y luego purgar su búfer.

Cómo funciona esto con un Play BodyParser, no estoy del todo seguro. ¡Más actualizaciones si puedo aclarar aún más lo que quiero hacer!

Aunque el archivo XML completo es grande, cada elemento <doc /> por sí solo es bastante pequeño, aunque obviamente tendría que comprobar que el búfer de bytes no superara un determinado tamaño.

+0

Es necesario rechunk adecuadamente sus NodeSeqs, ¿hay algún separador entre ellos? ¿Cómo sabes que un NodeSeq está completo? – Sadache

+0

Hola @Sadache: espero haber aclarado mi pregunta al respecto, gracias por echar un vistazo. – Mikesname

+0

Hola, ¿finalmente encontraste una solución? – Loic

Respuesta

3

Escaneo de los documentos parece que simplemente recoge esta información y abastecimientos de un org.w3c.Document todo para Java y un scala.xml de Scala: play xml requests

Eso parece muy poco probable para ayudar en su caso, a medida que' terminaré con un gran modelo de memoria. Para 100MB de xml, puede esperar un máximo de 700MB de uso para analizar.

Desafortunadamente, ninguna de las bibliotecas xml actualmente disponibles (y conocidas) admiten la alimentación en fragmentos según el modelo de Iteratee. Scales Xml proporciona una forma de procesar fragmentos de una secuencia (convirtiendo un analizador de arrastre en un enumerador); consulte here para ver ejemplos.

Como tal, actualmente recomendaría tomar un InputStream (o Reader) normal y alimentarlo en algo similar a Scales. Quizás un experto de Play pueda recomendar cómo recuperar una secuencia (sin procesarla completamente) desde el marco.

NB: La final actual está dentro de poco, pero la próxima versión principal (0.5) intentará aprovechar aalto-xml para permitir este procesamiento de flujo parcial (sin bloqueo) desde ambos lados.

+0

aalto-xml async reader parece muy interesante. En http://www.cowtowncoder.com/blog/archives/2011/03/entry_451.html parece que podría usarse en esta situación para generar un 'Enumerator' basado en la sucesiva' Array [Byte]] '. – huynhjl

+0

¿Es aalto-xml capaz de manejar trozos (xml parcial)? Me interesaría mucho ver algún ejemplo ... – Loic

1

El analizador Nux basado en XOM aceptará entrada fragmentada y está diseñado específicamente para la transmisión de archivos XML de gran tamaño. Parece exactamente lo que quieres.