Tengo documentos XML que necesito analizar y / o necesito construir documentos XML y escribirlos en texto (ya sea archivos o memoria). Dado que la biblioteca estándar de C ++ no tiene una biblioteca para esto, ¿qué debo usar?
Nota: Esto pretende ser una pregunta definitiva, C ++ - Preguntas frecuentes para esto. Entonces sí, es un duplicado de otros. No simplemente me apropié de esas otras preguntas porque tendían a pedir algo un poco más específico. Esta pregunta es más genérica.
c++
xml-parsing
c++-faq
Nicol Bolas
fuente
fuente
Respuestas:
Al igual que con los contenedores de biblioteca estándar, la biblioteca que debe usar depende de sus necesidades. Aquí hay un diagrama de flujo conveniente:
Entonces la primera pregunta es esta: ¿Qué necesitas?
Necesito cumplimiento completo de XML
OK, entonces necesitas procesar XML. No juguete XML, XML real . Debe poder leer y escribir todas las especificaciones XML, no solo los bits bajos y fáciles de analizar. Necesita espacios de nombres, DocTypes, sustitución de entidades, los trabajos. La especificación XML W3C, en su totalidad.
La siguiente pregunta es: ¿Su API debe ajustarse a DOM o SAX?
Necesito conformidad exacta de DOM y / o SAX
OK, entonces realmente necesitas que la API sea DOM y / o SAX. No puede ser simplemente un analizador push de estilo SAX, o un analizador retenido de estilo DOM. Se debe ser el DOM real o el SAX real, en la medida en que C ++ permite.
Has elegido:
Xerces
Esa es tu elección. Es prácticamente el único analizador / escritor XML C ++ que tiene conformidad DOM (y SAX) completa (o tan cerca como lo permite C ++). También tiene soporte XInclude, soporte de esquema XML y una gran cantidad de otras características.
No tiene dependencias reales. Utiliza la licencia de Apache.
No me importa el cumplimiento de DOM y / o SAX
Has elegido:
LibXML2
LibXML2 ofrece una interfaz de estilo C (si eso realmente te molesta, usa Xerces), aunque la interfaz está al menos algo basada en objetos y se ajusta fácilmente. Proporciona muchas características, como soporte XInclude (con devoluciones de llamada para que pueda decirle de dónde obtiene el archivo), un reconocedor XPath 1.0, soporte RelaxNG y Schematron (aunque los mensajes de error dejan mucho que desear), y etc.
Tiene una dependencia en iconv, pero se puede configurar sin esa dependencia. Aunque eso significa que tendrá un conjunto más limitado de posibles codificaciones de texto que puede analizar.
Utiliza la licencia MIT.
No necesito el cumplimiento completo de XML
OK, entonces el cumplimiento total de XML no te importa. Sus documentos XML están completamente bajo su control o tienen garantizado el uso del "subconjunto básico" de XML: sin espacios de nombres, entidades, etc.
Entonces, ¿qué te importa? La siguiente pregunta es: ¿Qué es lo más importante para usted en su trabajo XML?
Máximo rendimiento de análisis XML
Su aplicación necesita tomar XML y convertirlo en estructuras de datos C ++ tan rápido como pueda ocurrir esta conversión.
Has elegido:
RapidXML
Este analizador XML es exactamente lo que dice en la lata: XML rápido. Ni siquiera se trata de tirar el archivo a la memoria; cómo eso sucede depende de usted. Lo que sí trata es analizar eso en una serie de estructuras de datos de C ++ a las que puede acceder. Y lo hace tan rápido como se necesita para escanear el archivo byte a byte.
Por supuesto, no hay tal cosa como un almuerzo gratis. Como la mayoría de los analizadores XML que no se preocupan por la especificación XML, Rapid XML no toca espacios de nombres, DocTypes, entidades (con la excepción de las entidades de caracteres y los 6 XML básicos), y así sucesivamente. Básicamente, nodos, elementos, atributos y demás.
Además, es un analizador de estilo DOM. Por lo tanto, requiere que lea todo el texto. Sin embargo, lo que no hace es copiar nada de ese texto (generalmente). La forma en que RapidXML obtiene la mayor parte de su velocidad es haciendo referencia a las cadenas en el lugar . Esto requiere más administración de memoria por su parte (debe mantener esa cadena viva mientras RapidXML lo está mirando).
El DOM de RapidXML es básico. Puede obtener valores de cadena para cosas. Puede buscar atributos por nombre. Eso es todo. No hay funciones convenientes para convertir los atributos en otros valores (números, fechas, etc.). Solo tienes cuerdas.
Otra desventaja de RapidXML es que es doloroso escribir XML. Requiere que haga mucha asignación explícita de memoria de nombres de cadena para construir su DOM. Proporciona un tipo de búfer de cadena, pero eso aún requiere mucho trabajo explícito por su parte. Ciertamente es funcional, pero es difícil de usar.
Utiliza la licencia MIT. Es una biblioteca de solo encabezado sin dependencias.
Me importa el rendimiento, pero no tanto
Sí, el rendimiento es importante para ti. Pero tal vez necesites algo un poco menos básico. Quizás algo que pueda manejar más Unicode, o que no requiera tanta administración de memoria controlada por el usuario. El rendimiento sigue siendo importante, pero quieres algo un poco menos directo.
Has elegido:
PugiXML
Históricamente, esto sirvió de inspiración para RapidXML. Pero los dos proyectos han divergido, con Pugi ofreciendo más funciones, mientras que RapidXML se centra completamente en la velocidad.
PugiXML ofrece soporte de conversión Unicode, por lo que si tiene algunos documentos UTF-16 y desea leerlos como UTF-8, Pugi los proporcionará. Incluso tiene una implementación XPath 1.0, si necesita ese tipo de cosas.
Pero Pugi sigue siendo bastante rápido. Al igual que RapidXML, no tiene dependencias y se distribuye bajo la Licencia MIT.
Leer documentos enormes
Debe leer documentos que se miden en gigabytes de tamaño. Tal vez los está obteniendo de stdin, siendo alimentado por algún otro proceso. O los estás leyendo de archivos masivos. O lo que sea. El punto es que lo que necesita es no tener que leer todo el archivo en la memoria de una sola vez para poder procesarlo.
Has elegido:
LibXML2
La API de estilo SAX de Xerces funcionará en esta capacidad, pero LibXML2 está aquí porque es un poco más fácil trabajar con él. Una API de estilo SAX es una API de inserción: comienza a analizar una secuencia y simplemente dispara los eventos que tiene que atrapar. Estás obligado a gestionar el contexto, el estado, etc. El código que lee una API de estilo SAX está mucho más extendido de lo que cabría esperar.
El
xmlReader
objeto de LibXML2 es una API de extracción. Usted pide ir al siguiente nodo XML o elemento; no te lo dicen Esto le permite almacenar el contexto como mejor le parezca, para manejar diferentes entidades de una manera mucho más legible en código que un montón de devoluciones de llamada.Alternativas
Expatriado
Expat es un conocido analizador de C ++ que utiliza una API pull-parser. Fue escrito por James Clark.
Su estado actual es activo. La versión más reciente es 2.2.9, que se lanzó el (2019-09-25).
LlamaXML
Es una implementación de una API de estilo StAX. Es un analizador de extracción, similar al
xmlReader
analizador LibXML2 .Pero no se ha actualizado desde 2005. Una vez más, Caveat Emptor.
Soporte XPath
XPath es un sistema para consultar elementos dentro de un árbol XML. Es una forma práctica de nombrar efectivamente un elemento o colección de elementos mediante propiedades comunes, utilizando una sintaxis estandarizada. Muchas bibliotecas XML ofrecen soporte para XPath.
Hay efectivamente tres opciones aquí:
Solo haz el trabajo
Entonces, no te importa la corrección de XML. El rendimiento no es un problema para ti. La transmisión es irrelevante. Todo lo que quiere es algo que tenga XML en la memoria y le permita volver a pegarlo en el disco. Lo que te importa es la API.
Desea un analizador XML que sea pequeño, fácil de instalar, trivial de usar y lo suficientemente pequeño como para ser irrelevante para el tamaño de su ejecutable final.
Has elegido:
TinyXML
Puse TinyXML en esta ranura porque es tan fácil de usar como los analizadores XML. Sí, es lento, pero es simple y obvio. Tiene muchas funciones convenientes para convertir atributos, etc.
Escribir XML no es un problema en TinyXML. Simplemente
new
levante algunos objetos, adjúntelos, envíe el documento a unstd::ostream
, y todos estarán felices.También hay algo de un ecosistema construido alrededor de TinyXML, con una API más amigable para los iteradores, e incluso una implementación de XPath 1.0 en capas.
TinyXML usa la licencia zLib, que es más o menos la licencia MIT con un nombre diferente.
fuente
Hay otro enfoque para manejar XML que puede considerar, llamado enlace de datos XML. Especialmente si ya tiene una especificación formal de su vocabulario XML, por ejemplo, en XML Schema.
El enlace de datos XML le permite usar XML sin realizar ningún análisis o serialización XML. Un compilador de enlace de datos genera automáticamente todo el código de bajo nivel y presenta los datos analizados como clases de C ++ que corresponden al dominio de su aplicación. Luego trabaja con estos datos llamando a funciones y trabajando con tipos C ++ (int, double, etc.) en lugar de comparar cadenas y analizar texto (que es lo que hace con API de acceso XML de bajo nivel como DOM o SAX).
Vea, por ejemplo, una implementación de enlace de datos XML de código abierto que escribí, CodeSynthesis XSD y, para una versión más liviana y libre de dependencia, CodeSynthesis XSD / e .
fuente
Otra nota sobre Expat: vale la pena mirar para el trabajo de sistemas integrados. Sin embargo, la documentación que es probable que encuentre en la web es antigua e incorrecta. El código fuente en realidad tiene comentarios de nivel de función bastante completos, pero tomará un poco de lectura para que tengan sentido.
fuente
Pon el mío también.
http://www.codeproject.com/Articles/998388/XMLplusplus-version-The-Cplusplus-update-of-my-XML
Sin funciones de validación XML, pero rápido.
fuente
OK entonces. He creado uno nuevo, ya que ninguno de la lista no era suficiente para mis necesidades.
Beneficios:
Desventajas
Proyecto en casa
fuente
En Secured Globe , Inc. usamos rapidxml . Probamos todos los demás, pero rapidxml parece ser la mejor opción para nosotros.
Aquí hay un ejemplo:
fuente