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í:
- LibXML2 : Proporciona soporte completo para XPath 1.0. Nuevamente, es una API C, por lo que si eso te molesta, hay alternativas.
- PugiXML : también viene con soporte para XPath 1.0. Como se indicó anteriormente, es más una API de C ++ que LibXML2, por lo que puede sentirse más cómodo con ella.
- TinyXML : no viene con soporte XPath, pero existe la biblioteca TinyXPath que lo proporciona. TinyXML está experimentando una conversión a la versión 2.0, que cambia significativamente la API, por lo que TinyXPath puede no funcionar con la nueva API. Al igual que TinyXML, TinyXPath se distribuye bajo la licencia zLib.
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 un std::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.