Tout comme avec les conteneurs de bibliothèque standard, la bibliothèque que vous devez utiliser dépend de vos besoins. Voici un organigramme pratique:
La première question est donc la suivante: de quoi avez-vous besoin?
J'ai besoin d'une conformité XML complète
OK, vous devez donc traiter XML. Ce n'est pas un jouet XML, un vrai XML. Vous devez être en mesure de lire et d'écrire toutes les spécifications XML, pas seulement les bits de faible taille et faciles à analyser. Vous avez besoin d'espaces de noms, de DocTypes, de substitution d'entités, de travaux. La spécification XML W3C, dans son intégralité.
La question suivante est: votre API doit-elle être conforme à DOM ou SAX?
J'ai besoin d'une conformité DOM et / ou SAX exacte
OK, vous avez donc vraiment besoin que l'API soit DOM et / ou SAX. Il ne peut pas simplement s'agir d'un analyseur push de style SAX ou d'un analyseur conservé de style DOM. Il doit s'agir du DOM réel ou du SAX réel, dans la mesure où C ++ le permet.
Tu as choisi:
Xerces
C'est ton choix. C'est à peu près le seul analyseur / graveur XML C ++ qui a une conformité complète (ou aussi proche que C ++ le permet) DOM et SAX. Il prend également en charge XInclude, la prise en charge du schéma XML et une pléthore d'autres fonctionnalités.
Il n'a pas de réelles dépendances. Il utilise la licence Apache.
Je me fiche de la conformité DOM et / ou SAX
Tu as choisi:
LibXML2
LibXML2 propose une interface de style C (si cela vous dérange vraiment, allez utiliser Xerces), bien que l'interface soit au moins quelque peu basée sur des objets et facilement encapsulée. Il fournit de nombreuses fonctionnalités, comme la prise en charge de XInclude (avec des rappels pour que vous puissiez lui dire d'où il tire le fichier), un reconnaisseur XPath 1.0, la prise en charge de RelaxNG et Schematron (bien que les messages d'erreur laissent beaucoup à désirer), et ainsi de suite.
Il a une dépendance sur iconv, mais il peut être configuré sans cette dépendance. Bien que cela signifie que vous disposerez d'un ensemble plus limité d'encodages de texte possibles qu'il pourra analyser.
Il utilise la licence MIT.
Je n'ai pas besoin d'une conformité XML complète
OK, donc la conformité XML complète n'a pas d'importance pour vous. Vos documents XML sont entièrement sous votre contrôle ou sont garantis pour utiliser le "sous-ensemble de base" de XML: pas d'espaces de noms, d'entités, etc.
Alors qu'est-ce qui vous importe? La question suivante est: Quelle est la chose la plus importante pour vous dans votre travail XML?
Performances d'analyse XML maximales
Votre application doit prendre XML et le transformer en infrastructures de données C ++ aussi rapidement que cette conversion peut se produire.
Tu as choisi:
RapidXML
Cet analyseur XML est exactement ce qu'il dit sur l'étain: XML rapide. Il ne traite même pas de l'extraction du fichier en mémoire; comment cela se fait dépend de vous. Ce qu'il traite, c'est l'analyse de cela en une série de structures de données C ++ auxquelles vous pouvez accéder. Et il le fait aussi rapidement qu'il le faut pour analyser le fichier octet par octet.
Bien sûr, un déjeuner gratuit n'existe pas. Comme la plupart des analyseurs XML qui ne se soucient pas de la spécification XML, Rapid XML ne touche pas les espaces de noms, les DocTypes, les entités (à l'exception des entités de caractères et des 6 entités XML de base), etc. Donc, fondamentalement, les nœuds, les éléments, les attributs, etc.
Il s'agit également d'un analyseur de style DOM. Il faut donc que vous lisiez tout le texte. Cependant, ce qu'il ne fait pas, c'est de copier tout ce texte (généralement). La façon dont RapidXML obtient la plupart de sa vitesse est en se référant aux chaînes en place . Cela nécessite plus de gestion de la mémoire de votre part (vous devez garder cette chaîne en vie pendant que RapidXML la regarde).
Le DOM de RapidXML est simple. Vous pouvez obtenir des valeurs de chaîne pour les choses. Vous pouvez rechercher des attributs par nom. C'est à peu près ça. Il n'y a pas de fonctions pratiques pour transformer les attributs en d'autres valeurs (nombres, dates, etc.). Vous obtenez juste des cordes.
Un autre inconvénient de RapidXML est qu'il est pénible pour écrire du XML. Il vous oblige à faire beaucoup d'allocation de mémoire explicite des noms de chaîne afin de construire son DOM. Il fournit une sorte de tampon de chaîne, mais cela nécessite encore beaucoup de travail explicite de votre part. C'est certainement fonctionnel, mais c'est pénible à utiliser.
Il utilise la licence MIT. Il s'agit d'une bibliothèque uniquement en-tête sans dépendances.
Je me soucie de la performance mais pas tant que ça
Oui, la performance compte pour vous. Mais peut-être avez-vous besoin de quelque chose d'un peu moins dépouillé. Peut-être quelque chose qui peut gérer plus d'Unicode, ou qui ne nécessite pas autant de gestion de mémoire contrôlée par l'utilisateur. Les performances sont toujours importantes, mais vous voulez quelque chose d'un peu moins direct.
Tu as choisi:
PugiXML
Historiquement, cela a servi d'inspiration pour RapidXML. Mais les deux projets ont divergé, Pugi offrant plus de fonctionnalités, tandis que RapidXML se concentre entièrement sur la vitesse.
PugiXML offre un support de conversion Unicode, donc si vous avez des documents UTF-16 et que vous souhaitez les lire en UTF-8, Pugi vous fournira. Il a même une implémentation XPath 1.0, si vous avez besoin de ce genre de chose.
Mais Pugi est encore assez rapide. Comme RapidXML, il n'a pas de dépendances et est distribué sous la licence MIT.
Lire d'énormes documents
Vous devez lire des documents mesurés en gigaoctets . Peut-être que vous les obtenez de stdin, alimentés par un autre processus. Ou vous les lisez à partir de fichiers volumineux. Ou peu importe. Le fait est que ce dont vous avez besoin est de ne pas avoir à lire tout le fichier en mémoire d'un coup pour le traiter.
Tu as choisi:
LibXML2
L'API de style SAX de Xerces fonctionnera dans cette capacité, mais LibXML2 est là parce que c'est un peu plus facile à utiliser. Une API de style SAX est une API push: elle commence à analyser un flux et déclenche simplement les événements que vous devez intercepter. Vous êtes obligé de gérer le contexte, l'état, etc. Le code qui lit une API de style SAX est beaucoup plus répandu qu'on ne pourrait l'espérer.
L' xmlReader
objet de LibXML2 est une pull-API. Vous demandez d'aller au prochain nœud ou élément XML; on ne vous le dit pas. Cela vous permet de stocker le contexte comme bon vous semble, pour gérer différentes entités d'une manière beaucoup plus lisible dans le code qu'un tas de rappels.
Alternatives
Expat
Expat est un analyseur C ++ bien connu qui utilise une API pull-parser. Il a été écrit par James Clark.
Son état actuel est actif. La version la plus récente est la 2.2.9, qui a été publiée le (2019-09-25).
LlamaXML
Il s'agit d'une implémentation d'une API de style StAX. Il s'agit d'un analyseur par pull, similaire à l' xmlReader
analyseur de LibXML2 .
Mais il n'a pas été mis à jour depuis 2005. Encore une fois, Caveat Emptor.
Prise en charge XPath
XPath est un système pour interroger des éléments dans une arborescence XML. C'est un moyen pratique de nommer efficacement un élément ou une collection d'éléments par des propriétés communes, en utilisant une syntaxe standardisée. De nombreuses bibliothèques XML offrent le support XPath.
Il y a effectivement trois choix ici:
- LibXML2 : il fournit une prise en charge complète de XPath 1.0. Encore une fois, c'est une API C, donc si cela vous dérange, il existe des alternatives.
- PugiXML : Il est également compatible avec XPath 1.0. Comme ci-dessus, il s'agit plus d'une API C ++ que de LibXML2, vous pouvez donc être plus à l'aise avec elle.
- TinyXML : Il ne vient pas avec le support XPath, mais il y a la bibliothèque TinyXPath qui le fournit. TinyXML subit une conversion vers la version 2.0, qui modifie considérablement l'API, donc TinyXPath peut ne pas fonctionner avec la nouvelle API. Comme TinyXML lui-même, TinyXPath est distribué sous la licence zLib.
Faites simplement le travail
Donc, vous ne vous souciez pas de l'exactitude XML. La performance n'est pas un problème pour vous. Le streaming n'est pas pertinent. Tout ce que vous voulez, c'est quelque chose qui obtient XML en mémoire et vous permet de le coller à nouveau sur le disque. Ce qui vous intéresse, c'est l'API.
Vous voulez un analyseur XML qui sera petit, facile à installer, trivial à utiliser et suffisamment petit pour ne pas être pertinent pour la taille de votre éventuel exécutable.
Tu as choisi:
TinyXML
J'ai mis TinyXML dans cet emplacement car il est à peu près aussi simple à utiliser que les analyseurs XML. Oui, c'est lent, mais c'est simple et évident. Il a beaucoup de fonctions pratiques pour convertir des attributs et ainsi de suite.
L'écriture XML n'est pas un problème dans TinyXML. Vous venez de new
monter quelques objets, de les attacher ensemble, d'envoyer le document à un std::ostream
, et tout le monde est content.
Il y a aussi quelque chose d'un écosystème construit autour de TinyXML, avec une API plus conviviale pour les itérateurs, et même une implémentation XPath 1.0 superposée.
TinyXML utilise la licence zLib, qui est plus ou moins la licence MIT avec un nom différent.