example - xpath c#
¿Cuál es la mejor manera de usar XPath con archivos XML muy grandes en.NET? (10)
¿Has estado probando XPathDocument? Esta clase está optimizada para manejar consultas XPath de manera eficiente.
Si no puede manejar sus documentos de entrada de manera eficiente utilizando XPathDocument, podría considerar preprocesar y / o dividir sus documentos de entrada utilizando un XmlReader.
Necesito hacer algo de procesamiento en archivos XML bastante grandes (grandes aquí son potencialmente más de un gigabyte) en C #, incluida la realización de algunas consultas complejas de xpath. El problema que tengo es que la forma estándar en que normalmente haría esto a través de las bibliotecas System.XML es cargar todo el archivo en la memoria antes de que haga algo con él, lo que puede causar problemas de memoria con archivos de este tamaño.
No necesito actualizar los archivos, solo leerlos y consultar los datos que contienen. Algunas de las consultas XPath son bastante complicadas y abarcan varios niveles de relación entre padres e hijos. No estoy seguro de si esto afectará la capacidad de usar un lector de flujo en lugar de cargar los datos en la memoria como un bloque.
Una forma que puedo ver de hacerlo funcionar es realizar el análisis simple utilizando un enfoque basado en flujo y tal vez envolviendo las declaraciones XPath en transformaciones XSLT que luego podría ejecutar a través de los archivos, aunque parece un poco intrincado.
Alternativamente, sé que hay algunos elementos que las consultas XPath no ejecutarán, así que supongo que podría dividir el documento en una serie de fragmentos más pequeños en función de su estructura de árbol original, que tal vez podría ser lo suficientemente pequeña como para procesarla en la memoria sin causando demasiados estragos.
Intenté explicar mi objetivo aquí, así que si estoy hablando mal del árbol en términos de enfoque general, estoy seguro de que ustedes pueden arreglarme ...
¿Qué tal simplemente leer todo en una base de datos y luego trabajar con la base de datos temporal? Eso podría ser mejor porque sus consultas se pueden hacer de manera más eficiente utilizando TSQL.
Para realizar consultas XPath con las clases .NET estándar, el árbol de documentos completo debe cargarse en la memoria, lo que podría no ser una buena idea si puede tomar hasta un gigabyte. En mi humilde opinión, el XmlReader es una buena clase para manejar tales tareas.
Ya has delineado tus elecciones.
O necesita abandonar XPath y usar XmlTextReader o necesita dividir el documento en trozos manejables en los que puede usar XPath.
Si elige este último, utilice XPathDocument, su restricción de solo lectura permite un mejor uso de la memoria.
Parece que ya intentó usar XPathDocument
y no pudo acomodar el documento xml analizado en la memoria .
Si este es el caso, antes de comenzar a dividir el archivo (que en última instancia es la decisión correcta), puede intentar usar el procesador XSLT / XQuery de Saxon . Tiene una representación en memoria muy eficiente de un documento XML cargado (el modelo "tinytree" ). Además, Saxon SA (la versión compatible con shema, que no es gratuita) tiene algunas extensiones de transmisión . Lea más sobre esto aquí .
Creo que la mejor solución es crear su propio analizador xml que pueda leer fragmentos pequeños, no todo el archivo, o puede dividir el archivo grande en archivos pequeños y usar clases de puntos con estos archivos. El problema es que no puedes analizar algunos datos hasta que toda la información esté disponible, por lo que te recomiendo usar tus propias clases de analizador y no de dotnet.
Dado que en su caso el tamaño de los datos puede ejecutarse en Gbs, ha considerado usar ADO.NET con XML como base de datos. Además de eso, la huella de memoria no sería enorme.
Otro enfoque sería usar Linq a XML con el uso de elementos como XElementStream. Espero que esto ayude.
http://msdn.microsoft.com/en-us/library/bb387013.aspx tiene un ejemplo relevante aprovechando XStreamingElement.
XPathReader es la respuesta. No es parte del tiempo de ejecución de C #, pero está disponible para su descarga desde Microsoft. Aquí hay un artículo de MSDN .
Si construyes un XPathReader con un XmlTextReader obtienes la eficiencia de una lectura de transmisión con la conveniencia de las expresiones XPath.
No lo he usado en archivos de tamaño gigabyte, pero lo he usado en archivos que son decenas de megabytes, que generalmente es suficiente para desacelerar las soluciones basadas en DOM.
Citando de abajo: "XPathReader proporciona la capacidad de realizar documentos XPath sobre XML de forma continua".
Archivos Gigabyte XML! No te envidio esta tarea.
¿Hay alguna forma de que los archivos puedan enviarse de una mejor manera? Por ejemplo, ¿le están enviando a través de la red? Si lo están, entonces un formato más eficiente podría ser mejor para todos los interesados. Leer el archivo en una base de datos no es una mala idea, pero podría llevar mucho tiempo.
No trataría de hacerlo todo en la memoria leyendo todo el archivo, a menos que tenga un sistema operativo de 64 bits y mucha memoria. ¿Qué pasa si el archivo se convierte en 2, 3, 4GB?
Otro enfoque podría ser leer en el archivo XML y usar SAX para analizar el archivo y escribir archivos XML más pequeños de acuerdo con alguna división lógica. A continuación, puede procesar estos con XPath. He usado XPath en archivos de 20-30MB y es muy rápido. Originalmente iba a usar SAX, pero pensé que iba a darle una oportunidad a XPath y me sorprendió lo rápido que fue. Ahorré mucho tiempo de desarrollo y probablemente solo perdí 250 ms por consulta. Estaba usando Java para mi análisis, pero sospecho que habría poca diferencia en .NET.
Leí que XML :: Twig (un módulo Perl CPAN) se escribió explícitamente para manejar el análisis XPath basado en SAX. ¿Puedes usar un idioma diferente?
Esto también podría ayudar a https://web.archive.org/web/1/http://articles.techrepublic%2ecom%2ecom/5100-10878_11-1044772.html