2008-10-23 13 views
5

Necesito una herramienta para ejecutar XSLTs contra archivos XML de gran tamaño. Para que quede claro, no necesito nada para diseñar, editar o depurar los XSLT, simplemente ejecútelos. Las transformaciones que estoy usando ya están bien optimizadas, pero los archivos grandes están causando que la herramienta que he probado (Saxon v9.1) se quede sin memoria.Procesador XSLT de memoria eficiente

+0

Cambie el título de la pregunta a algo así como: "Procesador XSLT con poca memoria". No está interesado en "todo lo mejor", sino específicamente en "el mejor de los archivos más grande que la RAM". – ddaa

+0

Tal vez "Proceso XSLT para archivos más grandes que RAM". – ddaa

+0

@SantoshK, parece que pegaste accidentalmente en un enlace a esta misma pregunta. Es decir, ha vinculado a la pregunta # 230702, y esta es la pregunta # 230702. –

Respuesta

5

Encontré una buena solución: Xalan C++ de Apache. Proporciona un pluggable memory manager, lo que me permite ajustar la asignación en función de la entrada y la transformación.

En muchos casos consume ~ 60% menos memoria (estoy buscando bytes privados) que los otros que he probado.

+0

Todavía no es bueno para "procesar archivos que son más grandes que la RAM", pero si es lo suficientemente bueno para usted, genial. – ddaa

-2

Tome un vistazo a Xselerator

+0

Presumiblemente votada porque el enlace (y la herramienta) ya no es válido/no está disponible. –

1

He encontrado que una herramienta hecha a la medida para ejecutar el XSLT utilizando versiones anteriores de MSXML hace que sea muy rápido, sino que también consume una increíble cantidad de memoria, y no realmente completa si es demasiado grande También se pierde una funcionalidad XSLT avanzada, ya que las versiones anteriores de MSXML no son compatibles con todo el material de xpath.

Vale la pena intentarlo si sus otras opciones toman demasiado tiempo.

+0

¡El secreto sucio por un tiempo fue el hecho de que los primeros equivalentes .Net de MSXML 4.0 eran realmente lentos! –

1

Esa es una pregunta interesante. XSLT podría potencialmente optimizarse para el espacio, pero espero que todas las implementaciones menos las más oscuras comiencen por analizar el documento de origen en DOM, que está destinado a usar un bajo múltiplo del tamaño del documento en la memoria.

A menos que la hoja de estilo esté especialmente diseñada para admitir una transformación de paso único, un rendimiento de tiempo razonable probablemente requeriría analizar el documento de origen en una base de datos jerárquica basada en disco.

No tengo una respuesta, sin embargo.

+0

Sí, esto describe bien el problema subyacente. –

2

Parece que está ordenado, pero a menudo, otro enfoque posible es dividir primero los datos. Obviamente, esto solo funciona con algunas transformaciones (es decir, donde diferentes trozos de datos se pueden tratar de forma aislada del todo), pero luego puede usar un analizador simple (en lugar de un DOM) para dividirlo en partes manejables, luego procesar cada fragmento por separado y volver a armar.

Como soy un bod de .NET, cosas como XmlReader pueden hacer la fragmentación sin un DOM; Estoy seguro de que hay equivalentes para cada idioma.

Nuevamente, solo por completitud.

[edit re question] No conozco ningún nombre específico; tal vez Divide and Conquer. Para un ejemplo; Si sus datos son realmente una lista plana de objetos similares, entonces podría simplemente dividir a los niños de primer nivel, es decir, en lugar de tener filas de 2M, divídalo en 10 lotes de 200K filas o 100 lotes de 20K filas. He hecho esto muchas veces antes para trabajar con datos masivos (por ejemplo, cargar en fragmentos de datos [todos válidos) y volver a ensamblar en el servidor para que cada carga individual sea lo suficientemente pequeña como para ser robusta).

+0

Gracias Marc, esa es una gran idea. Me puede decir mas acerca de eso? ¿Hay un nombre para esta técnica para poder investigarlo? –

0

¿Está utilizando la versión Java de Saxon o el puerto .Net? Puede asignar más memoria a la máquina virtual de Java que ejecuta Saxon, si se está quedando sin memoria (utilizando el parámetro de línea de comandos -Xms).

También encontré que la versión .Net de Saxon se queda sin memoria con menos facilidad que la versión de Java.

3

Es posible que desee consultar STX para realizar transformaciones basadas en transmisión XSLT. Alternativamente, creo que StAX puede integrate with XSLT nicely a través de la interfaz del transformador.

+0

Gracias por agregar esto: STX era completamente nuevo para mí. –

2

Por lo que vale, sospecho que para Java, Saxon es tan bueno como se pone, si necesita usar XSLT. Es bastante eficiente (tanto en la CPU como en la memoria) para documentos más grandes, pero el propio XSLT básicamente obliga a crear y conservar el árbol de contenido completo en memoria, excepto en casos limitados. Saxon-SA (versión de pago) supuestamente tiene extensiones para permitir el aprovechamiento de tales casos de "transmisión", por lo que podría valer la pena examinar.

Pero el consejo para dividir el contenido es el mejor: si se trata de registros independientes, simplemente dividir la entrada utilizando otras técnicas (como, utilizar Stax :-)!)

0

Para .NET puede utilizar la sugerencia de solución en Microsoft Knowledge Base: http://support.microsoft.com/kb/307494

XPathDocument srcDoc = new XPathDocument(srcFile); 
XslCompiledTransform myXslTransform = new XslCompiledTransform(); 
myXslTransform.Load(xslFile); 
using (XmlWriter destDoc = XmlWriter.Create(destFile)) 
{ 
    myXslTransform.Transform(srcDoc, destDoc); 
} 
1

parece que Saxon 9.2 puede proporcionar una respuesta a su problema. Si su documento se puede transformar sin usar predicados (no hace referencia a ningún hermano del nodo actual), puede usar Streaming XSLT. Ver this link

No he probado esto por mi cuenta, solo estoy leyendo al respecto. Pero espero que funcione

Cuestiones relacionadas