2011-08-27 18 views
6

El archivo de entrada contiene miles de transacciones en formato XML que tiene un tamaño de alrededor de 10 GB. El requisito es elegir cada transacción XML en función de la entrada del usuario y enviarla al sistema de procesamiento.Lectura de archivos XML en gran cantidad usando StAX y XPath

El contenido de la muestra del archivo

<transactions> 
    <txn id="1"> 
     <name> product 1</name> 
     <price>29.99</price> 
    </txn> 

    <txn id="2"> 
     <name> product 2</name> 
     <price>59.59</price> 
    </txn> 
</transactions> 

Se espera que el usuario (técnica) para dar el nombre de la variable de entrada como <txn>.

Queremos brindarle esta solución para que sea más genérica. El contenido del archivo puede ser diferente y los usuarios pueden dar una expresión XPath como "//transactions/txn" para elegir transacciones individuales.

Hay pocas cosas técnicas que tenemos que considerar aquí

  • El archivo puede estar en una ubicación FTP o
  • compartida Dado que el tamaño del archivo es enorme, que no puede cargar el archivo completo JVM en

podemos utilizar StAX analizador para este escenario? Tiene que tomar la expresión XPath como entrada y seleccionar/seleccionar XML de transacción.

En busca de sugerencias. Gracias por adelantado.

+0

Mi recomendación es usar extendida ETV-XML en modo de mapa MEM y 64 bit jvm –

Respuesta

8

Stax y xpath son cosas muy diferentes. Stax le permite analizar un documento XML de transmisión en una dirección de avance solamente. Xpath permite el análisis en ambas direcciones. Stax es un analizador XML de transmisión muy rápido, pero, si quieres xpath, java tiene una biblioteca separada para eso.

Tome un vistazo a esta pregunta para una discusión muy similar: Is there any XPath processor for SAX model?

+2

Si me vas a rechazar, por favor deja un comentario. ¡De esa forma todos aprenden! – Jon7

+0

Bajar la votación porque su afirmación "Stax y xpath son cosas muy diferentes" no es correcta. XPath (al menos el subconjunto de esto) todavía se puede implementar en el modelo Stax (pull-model). Está implementado en C# https://msdn.microsoft.com/en-us/library/ms950778.aspx – TriCore

0

¿Necesita procesarlo rápido o necesita búsquedas rápidas en los datos? Estos requisitos necesitan un enfoque diferente.

Para una lectura rápida de todos los datos, StAX estará bien.

Si necesita búsquedas rápidas de las que podría necesitar cargar en alguna base de datos, Berkeley DB XML p.

1

Es definitivamente un caso de uso para XProc con un streaming y aplicación de procesamiento paralelo como QuiXProc (http://code.google.com/p/quixproc)

En esta situación, usted tendrá que usar

<p:for-each> 
    <p:iteration-source select="//transactions/txn"/> 
    <!-- you processing on a small file --> 
    </p:for-each> 

Incluso puede WRAPP cada una de las dando como resultado la transformación con una sola línea de XProc

<p:wrap-sequence wrapper="transactions"/> 

esperanza esto ayuda

1

Analizamos regularmente archivos XML complejos de 1GB + utilizando un analizador SAX que hace exactamente lo que usted describió: extrae árboles DOM parciales que pueden consultarse convenientemente mediante XPATH.

Me atiboré al respecto here - Está utilizando un analizador SAX no un StAX, pero puede valer la pena examinarlo.

13

Si el rendimiento es un factor importante, y/o el tamaño del documento es grande (ambos parecen ser el caso aquí), la diferencia entre un analizador de eventos (como SAX o StAX) y la implementación Java XPath nativa es que este último crea un documento W3C DOM antes de evaluar la expresión XPath. [Es interesante observar que todas las implementaciones de Java Document Object Model como DOM o Axiom usan un procesador de eventos (como SAX o StAX) para construir la representación en memoria, por lo que si alguna vez puede funcionar solo con el procesador de eventos que está guardando tanto la memoria como el tiempo que lleva construir un DOM.]

Como mencioné anteriormente, la implementación de XPath en el JDK opera sobre un documento W3C DOM. Esto se puede ver en la implementación del código fuente de Java JDK examinado com.sun.org.apache.xpath.internal.jaxp.XPathImpl, donde antes del método de evaluar() se llama el analizador debe primero analizar la fuente:

Document document = getParser().parse(source); 

Después de esto su 10GB de XML serán representados en la memoria (más cualquier gasto adicional) — probablemente no sea lo que quiere. Si bien es posible que desee una solución más "genérica", tanto su XPath de ejemplo como su marcado XML parecen relativamente simples, por lo que no parece haber una justificación sólida para una XPath (excepto tal vez programación de elegancia). Lo mismo ocurriría con la sugerencia de XProc: esto también generaría un DOM. Si realmente necesita un DOM, podría usar Axiom en lugar del W3C DOM. Axiom tiene una API mucho más amigable y construye su DOM sobre StAX, por lo que es rápido y utiliza Jaxen para su implementación de XPath. Jaxen requiere algunos tipo de DOM (W3C DOM, DOM4J o JDOM). Esto será cierto para todas las implementaciones de XPath, por lo que si realmente no necesita quedarse con XPath solo se recomienda el analizador de eventos.

SAX es la antigua API de transmisión, con StAX más nuevo y mucho más rápido. Ya sea utilizando la implementación nativa JDK StAX (javax.xml.stream) o la implementación StAX Woodstox (que es significativamente más rápida, según mi experiencia), recomendaría crear un filtro de eventos XML que coincida primero con el nombre del tipo de elemento (para capturar los elementos <txn>). Esto creará pequeñas ráfagas de eventos (elemento, atributo, texto) que se pueden verificar para los valores de usuario coincidentes. Con una coincidencia adecuada, puede extraer la información necesaria de los eventos o canalizar los eventos acotados para crear un mini-DOM a partir de ellos si encuentra que el resultado es más fácil de navegar. Pero parece que eso podría ser exagerado si el marcado es simple.

Este sería probablemente el enfoque más simple, más rápido posible y evitaría la sobrecarga de memoria de construir un DOM. Si pasó los nombres del elemento y el atributo al filtro (para que el algoritmo de coincidencia sea configurable) podría hacerlo relativamente genérico.

+0

¿Has oído hablar de vtd-xml? –

+0

No hasta su comentario, no, no lo hice. He descargado la distribución y estaré encantado de probarla. Si funciona como se dice, consideraría usarlo en entornos de producción, pero el enganche que veo me inclina a preguntar (ya que usted es el autor) si también estaría dispuesto a lanzar vtd-xml bajo una LGPL o Apache. ¿licencia? Simplemente no podemos usar GPL en nuestro entorno. Gracias por la propina en cualquier caso. –

+0

¿Está distribuyendo el código o simplemente lo usa internamente? –

0

Una solución divertida para procesar archivos XML de gran tamaño> 10 GB.

  1. Utilice ANTLR para crear desfases de bytes para las partes de su interés. Esto ahorrará algo de memoria en comparación con un enfoque basado en DOM.
  2. Uso JAXB para leer partes de posición de byte

encontrar los detalles en el ejemplo de Wikipedia volcados (17GB) en este SO responder https://stackoverflow.com/a/43367629/1485527

Cuestiones relacionadas