2011-10-12 35 views
6

Tengo el siguiente problema: Tengo archivos XML muy grandes (como más de 300 Megas), y necesito analizarlos para agregar algunos de sus valores a la base de datos. La estructura de estos archivos también es muy compleja. Quiero usar Stax Parser, ya que ofrece la buena posibilidad de extraer-analizar (y así procesar) solo partes del archivo XML a la vez, y así no cargar todo en la memoria, pero por otro lado obtener los valores con Stax (al menos en estos archivos XML) es engorroso, necesito escribir toneladas de código. Desde este último punto de vista, me será de gran ayuda si pudiera ordenar el archivo XML en objetos Java (como lo hace JAX-B), pero esto cargaría todo el archivo más una tonelada de instancias de objetos en la memoria, todo a la vez.Analizando archivos XML muy grandes y clasificándolos en objetos Java

Mi pregunta es, ¿hay alguna forma de analizar (o solo analizar parcialmente) el archivo secuencialmente, y luego ordenar solo esas partes en objetos Java para que pueda manejarlas fácilmente sin atascarme la memoria?

Respuesta

2

Bueno, antes que nada quiero dar las gracias a las dos personas responder a mis preguntas, pero finalmente terminó por no usar esas proposiciones en parte porque esas tecnologías propuestas son un poco lejos de la Java de dejar diga "análisis XML estándar" y se siente raro llegar tan lejos cuando hay una herramienta similar ya presente en Java y en parte también porque de hecho encontré una solución que solo usa las API de Java para lograr esto.

No detallaré demasiado la solución que encontré, porque ya he terminado la implementación, y es una gran parte del código para colocar aquí (uso Spring Batch en la parte superior de todo, con un montón de configuración y esas cosas).

yo sin embargo hacer un pequeño comentario sobre lo que finalmente terminó haciendo:

La gran idea aquí es el hecho de que si usted tiene un documento XML y es esquema XSD correspondiente, puede analizar & Marshall con JAXB, y puedes hacerlo en fragmentos, y dichos fragmentos pueden leerse con un analizador par, como STAX, y luego pasarse al JAXB Marshaller.

Esto prácticamente significa que primero debe decidir dónde está un buen lugar en su archivo XML donde puede decir "esta parte aquí tiene MUCHA estructura repetitiva, trataré esas repeticiones de a una por vez". Esas partes repetitivas suelen ser la misma etiqueta (infantil) que se repite mucho dentro de una etiqueta principal. Entonces, todo lo que tiene que hacer es crear un detector de eventos en su analizador STAX que se activa al inicio de cada una de esas etiquetas secundarias, luego transmitir a JAXB el contenido de esa etiqueta secundaria, direccionarlo con JAXB y procesarlo.

Realmente la idea está excelentemente descrita en este artículo, que seguí (es cierto, es de 2006, pero trata de JDK 1.6 que en ese momento era bastante nuevo, por lo que no es tan antiguo):

http://www.javarants.com/2006/04/30/simple-and-efficient-xml-parsing-using-jaxb-2-0/

+0

Es bueno saber que su problema está resuelto. Me pregunto cómo es esto (Soln en esta publicación) diferente de lo que he publicado? – Kashyap

+0

Bueno, sinceramente, era parte del miedo a los grandes frameworks, parte de pereza :) (ambos son malos y lamentables). En primer lugar, de la documentación EMF parece un marco bastante complicado, no es solo para el procesamiento de XML sino para muchas otras cosas, y siempre trato de evitar marcos tan pesados ​​siempre que sea posible (esto es solo preferencia personal, no soy decir es malo hacerlo en general). En segundo lugar, soy flojo y el EMF utiliza API de análisis XML no estándar que no conozco, por lo que también preferí la solución con las API Java XML estándar. –

+1

De hecho, tanto si le gustaron los campos electromagnéticos como si no, le recomendé NO usarlo ("** porque los campos electromagnéticos son demasiado grandes para un problema tan pequeño. **") a menos que no tenga otra opción. Y abt el analizador sintáctico, para citar nuevamente "así que ** simplemente analice usando lo que quiera **, cree algo de StringStream o algo por cada en un bucle y ** pase a JAX-B o EMF. **" – Kashyap

5

Recomendaría Eclipse EMF. Pero tiene el mismo problema, si le das el nombre del archivo, lo analizará todo. Aunque hay algunas opciones para reducir la cantidad que se carga, pero no me molestó mucho ya que corremos en máquinas con 96 GB de RAM. :)

De todos modos, si su formato XML está bien definido, entonces una solución alternativa es engañar al EMF dividiendo todo el archivo en varios fragmentos XML más pequeños (pero aún bien definidos). Luego, alimenta cada fragmento uno tras otro. No sé JAX-B, pero quizás la misma solución alternativa se puede aplicar allí también. Lo que recomendaría, porque EMF es un martillo demasiado grande para un problema tan pequeño.

Sólo para elaborar un poco si su XML tiene el siguiente aspecto:

<tag1> 
    <tag2> 
     <tag3/> 
     <tag4> 
      <tag5/> 
     </tag4> 
     <tag6/> 
     <tag7/> 
    </tag2> 

    <tag2> 
     <tag3/> 
     <tag4> 
      <tag5/> 
     </tag4> 
     <tag6/> 
     <tag7/> 
    </tag2> 
............ 
    <tag2> 
     <tag3/> 
     <tag4> 
      <tag5/> 
     </tag4> 
     <tag6/> 
     <tag7/> 
    </tag2> 
</tag1> 

continuación, se puede descomponer en un XML a partir de cada uno <tag2> y terminando con </tag2>. Y en Java la mayoría de los analizadores aceptaría un Stream, por lo que simplemente analice usando lo que desee, cree algo de StringStream o algo por cada <tag2> en un bucle y pase a JAX-B o EMF.

HTH

+0

Esto es algo que suena muy bien y que voy a tratar mañana a primera hora (es medianoche aquí ahora :)). Gracias por la sugerencia, suena prometedor –

+1

@thekashyap. ¿Puedo tener una de esas máquinas, plesae? ¡Solo uno! –

+0

Hehe .. Esas son nuestras máquinas de prueba, en mi casa trabajo en una computadora portátil Win7 con 4GB como todos los demás .. :) – Kashyap

1

proyección de documentos podría ser la respuesta aquí. Saxon y varios otros procesadores XQuery ofrecen esto como una opción. Si tiene una consulta razonablemente simple que selecciona una pequeña cantidad de datos de un documento grande, el procesador de consultas analiza la consulta para determinar qué partes del árbol deben estar disponibles para la consulta y cuáles pueden descartarse durante el procesamiento. El árbol resultante a menudo puede ser solo el 1% del tamaño del documento completo. Detalles para Saxon aquí:

http://saxonica.com/documentation/sourcedocs/projection.xml

Cuestiones relacionadas