2011-01-12 14 views
9

Bueno, se han hecho muchas preguntas sobre el análisis de XML en C++ y así sucesivamente ... Pero, en lugar de un problema genérico, el mío es muy específico.Análisis XML de alto rendimiento en C++

Estoy pidiendo un analizador XML muy eficiente para C++. En particular, tengo un archivo XML MUY MUY GRANDE para analizar. Mi aplicación debe abrir este archivo y recuperar datos. También debe insertar nuevos nodos y guardar el resultado final en el archivo nuevamente.

Para hacer esto utilicé, al principio, rapidxml, pero me requiere abrir el archivo, analizarlo todo (todo el contenido porque esta lib no tiene funciones para acceder al archivo directamente sin cargar todo el árbol primero) , luego edite el árbol, modifíquelo y almacene el árbol final en el archivo sobrescribiéndolo ... Consume demasiados recursos.

¿Hay un analizador XML que no requiera que cargue todo el archivo, pero que pueda usar para insertar, rápidamente, nuevos nodos y recuperar datos? ¿Puedes indicar soluciones para este problema mío?

+5

"Alto rendimiento xml" - ¿No es eso un oxímoron? –

+1

:) bien podría ser ... – Andry

+0

De uno de los creadores de este sitio, por qué XML no es una base de datos: http://www.joelonsoftware.com/articles/fog0000000319.html – MSalters

Respuesta

10

Desea un analizador XML de transmisión en lugar de lo que se denomina un analizador DOM.

Hay dos tipos de analizadores de transmisión: pull y push. Un analizador de extracción es bueno para escribir rápidamente analizadores XML que cargan datos en la memoria del programa. Un analizador de inserción es bueno para escribir un programa para traducir un documento a otro (que es lo que está tratando de lograr). Creo, por lo tanto, que un analizador sintáctico sería lo mejor para su problema.

Para utilizar un analizador de inserción, necesita escribir lo que es esencialmente un controlador de eventos para analizar eventos. Al decir "evento de análisis" me refiero a eventos como "etiqueta de inicio alcanzada", "etiqueta finalizada", "texto encontrado", "atributo analizado", etc.

sugiero que a medida que lee en el documento, escriba sacar el documento transformado a un archivo separado y temporal. Por lo tanto, sus manejadores de eventos de análisis XML deberán escribirse de forma que sean estables y escribir el XML del documento traducido de forma incremental.

Tres excelentes bibliotecas del analizador de inserción para C++ incluyen Expat, Xerces-C++ y libxml2.

+2

Si usa un analizador SAX de extracción o inserción, el resultado final es el mismo. Ambos requieren que se utilicen manejadores de eventos mientras los datos XML se analizan en fragmentos. La única diferencia entre ellos es que un analizador de extracción recupera automáticamente los datos de una fuente que especifique (como un archivo), mientras que un analizador de inserción le permite obtener los datos usted mismo y pasarlos al analizador (en este sentido, un analizador de extracción usa un empujar el modelo internamente). Sin embargo, ambos analizadores tienen el mismo tipo de lógica interna: dado un fragmento de datos, analízalo y dispara eventos según sea necesario, luego tira/espera el siguiente fragmento y repite ... –

+2

... así que tus controladores de eventos de SAX pueden extraer los datos según sea necesario en tiempo real mientras el XML se analiza en fragmentos, y luego puede escribir los datos suministrados en un archivo temporal, escribir nuevos datos donde sea necesario y luego reemplazar el archivo original con el archivo temporal cuando termine. –

+1

Además, uso libxml2 en mi código C++, funciona muy bien. Es compatible con los modelos DOM y SAX (pull and push). –

2

Estoy convencido de que no existe una biblioteca XML que le permita modificar un archivo sin cargarlo primero. Esto simplemente no es posible porque los archivos no funcionan de esa manera: no se puede insertar (o eliminar) en el medio de un archivo. Solo puede sobrescribir un bloque de tamaño idéntico, o anexar al final. Pero su solicitud requeriría anexar o eliminar en el medio del archivo.

Es posible que solo se puedan leer partes de un archivo XML. Pero escribiendo ... de ninguna manera.

+0

Bueno, no ... es posible No es necesario ordenar, se realiza más tarde, al tokenizar el archivo, puede ubicar un nodo y en su interior insertar el nuevo nodo ... no es necesario obtener el archivo completo ... ¿no? – Andry

+1

@Andry: mal. Ordenar * es * necesario en un archivo XML. Es posible que no lo necesite, pero el estándar XML exige que el orden de los nodos sea fijo. Además, la tokenización (en particular, encontrar el token * end * correspondiente) implica leer todo el archivo. –

+0

Gracias ... sí, tiene razón ... entonces las cosas se ponen mucho más difíciles ... Me pregunto cómo las bibliotecas en C# o idiomas de alto nivel pueden analizar archivos xml muy grandes en pocos milisegundos .... – Andry

5

Buscar "Analizador SAX". En su mayoría son tokenizadores, es decir, emiten etiqueta por etiqueta sin construir un árbol.

+0

Está el conocido Xerces, ¿es bueno para mis requisitos ???? – Andry

+1

@Andry dicen que Xerces tiene/admite SAX, por lo que probablemente esto funcione para usted. –

3

Los analizadores SAX son más rápidos que los analizadores DOM porque los analizadores DOM los leen en memoria antes de construir una representación en memoria del documento XML, mientras que un analizador SAX se comporta como un detector de eventos y crea el documento tal como se lee en el archivo. Go here para una explicación.

Como mencionaste Xerces es un buen analizador de C++ SAX.

Recomendaría buscar maneras de dividir el documento XML en documentos XML más pequeños, ya que eso parece ser parte de su problema.

2

Bien, aquí hay una ruta fuera de lo común, miré esto, pero realmente no lo he usado, se llama asmxml. Estos muchachos dicen que no tienen nada de desempeño, desventaja, necesitas un ensamblador x86.

+1

@downvoter, por favor explique? Solo estaba resaltando un analizador inusual que afirma tener un mejor rendimiento que la mayoría de analizadores principales, ¿qué hay de malo en lo que dije? – Nim

+0

Creo que el voto a favor se debió a que el OP especificó un analizador en C++. –

+0

@Chris, hmm, el analizador está escrito en ensamblador sí, pero está destinado a ser utilizado en aplicaciones C++. ¡No me hubiera molestado en publicarlo de otra manera! :( – Nim

1

Si realmente buscas analizador de flujo XML de alto rendimiento entonces libhpxml es probablemente lo correcto para ti.

0

Vaya por bibliotecas de plantillas tanto como sea posible, como Boost :: property_tree o Boost :: XMLParser o POCO :: XML y Folly tiene XML Parser en él.

Evita las antiguas librerías C, es decir, todos los diseños de códigos antiguos.

-1

Alguien dice que el módulo QtXML es de alto rendimiento para grandes archivos XML.