web-dev-qa-db-fra.com

Quel analyseur XML dois-je utiliser en C++?

J'ai des documents XML que je dois analyser et/ou j'ai besoin de construire des documents XML et de les écrire en texte (fichiers ou mémoire). Puisque la bibliothèque standard C++ ne possède pas de bibliothèque pour cela, que dois-je utiliser?

Remarque: Ceci est censé être une question définitive de type FAQ pour C++. Alors oui, c'est un duplicata des autres. Je ne me suis pas simplement approprié ces autres questions, car elles avaient tendance à demander quelque chose de légèrement plus précis. Cette question est plus générique.

307
Nicol Bolas

Tout comme avec les conteneurs de bibliothèque standard, la bibliothèque à utiliser dépend de vos besoins. Voici un organigramme pratique:

enter image description here

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. Non jouet XML, real XML. Vous devez être capable de lire et d'écrire all == de la spécification XML, pas seulement les bits de bas niveau, faciles à analyser. Vous avez besoin d'espaces de noms, de DocTypes, de substitution d'entités, de travaux. La spécification XML du W3C, dans son intégralité.

La question suivante est la suivante: Votre API doit-elle être conforme à DOM ou à SAX?

J'ai besoin d'une conformité exacte au DOM et/ou à SAX

OK, il faut donc que l’API soit DOM et/ou SAX. Il ne peut s'agir simplement d'un analyseur Push de style SAX ou d'un analyseur conservé de style DOM. Il doit soit le DOM actuel ou le 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 possède une conformité totale (ou aussi proche que C++ le permet) aux normes DOM et SAX. Il prend également en charge XInclude, XML Schema et de nombreuses autres fonctionnalités.

Il n'a pas de réelles dépendances. Il utilise la licence Apache.

Je me moque de la conformité DOM et/ou SAX

Tu as choisi:

LibXML2

LibXML2 offre une interface de style C (si cela vous dérange vraiment, utilisez Xerces), bien que l'interface soit au moins quelque peu basée sur les objets et facile à encapsuler. Il fournit un grand nombre de fonctionnalités, telles que le support XInclude (avec des rappels afin que vous puissiez indiquer d'où provient le fichier), un identificateur XPath 1.0, le support RelaxNG et Schematron (bien que les messages d'erreur laissent un lot à désirer), etc.

Il a une dépendance sur iconv, mais il peut être configuré sans cette dépendance. Bien que cela signifie que vous aurez un ensemble plus limité d'encodages de texte qu'il peut analyser.

Il utilise la licence MIT.

Je n'ai pas besoin de la conformité XML complète

OK, la conformité XML complète n'a donc aucune importance. Vos documents XML sont soit entièrement sous votre contrôle, soit qu’il est garanti d’utiliser le "sous-ensemble de base" de XML: aucun espace de nom, aucune entité, etc.

Alors, qu'est-ce qui compte pour vous? La prochaine question est: Quelle est la chose la plus importante pour vous dans votre travail XML?

Performance d'analyse XML maximale

Votre application doit prendre XML et la transformer en infrastructures de données C++ aussi rapidement que cette conversion peut éventuellement se produire.

Tu as choisi:

RapidXML

Cet analyseur XML est exactement ce qu'il dit sur l'étain: XML rapide. Cela ne traite même pas de mettre le fichier en mémoire; comment cela se passe est à vous. Ce que cela traite, c’est de l’analyser dans une série de structures de données C++ auxquelles vous pouvez accéder. Et cela se fait à peu près aussi vite que nécessaire pour analyser le fichier octet par octet.

Bien sûr, le déjeuner gratuit n'existe pas. Comme la plupart des analyseurs syntaxiques XML qui ne se soucient pas de la spécification XML, Rapid XML ne concerne 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.

En outre, il s'agit d'un analyseur syntaxique de style DOM. Donc, il faut que vous lisiez tout le texte. Cependant, il ne fait pas copy aucun de ce texte (généralement). RapidXML tire le meilleur parti de sa vitesse en faisant référence à des chaînes in-place . Cela nécessite davantage de gestion de la mémoire de votre part (vous devez garder cette chaîne vivante pendant que RapidXML l'examine).

Le DOM de RapidXML est sans faille. Vous pouvez obtenir des valeurs de chaîne pour des choses. Vous pouvez rechercher des attributs par nom. C'est à peu près ça. Il n’existe pas de fonctions pratiques permettant de transformer des attributs en d’autres valeurs (nombres, dates, etc.). Vous avez juste des cordes.

Un autre inconvénient de RapidXML est que cela est douloureux pour écrit XML. Cela 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 demande quand même beaucoup de travail explicite de votre part. C'est certainement fonctionnel, mais c'est pénible à utiliser.

Il utilise la licence MIT. C'est une bibliothèque en-tête uniquement sans dépendance.

Je me soucie de la performance mais pas autant que ça

Oui, la performance compte pour vous. Mais peut-être avez-vous besoin de quelque chose d'un peu moins dénudé. Peut-être que quelque chose peut gérer plus d'Unicode, ou n'exige pas autant de gestion de mémoire contrôlée par l'utilisateur. La performance est toujours importante, mais vous voulez quelque chose d'un peu moins direct.

Tu as choisi:

PugiXML

Historiquement, cela a servi d’inspiration à RapidXML. Mais les deux projets ont divergé, Pugi offrant davantage de fonctionnalités, tandis que RapidXML est entièrement centré sur la vitesse.

PugiXML offre un support de conversion Unicode, donc si vous avez des documents UTF-16 et que vous voulez les lire en tant que UTF-8, Pugi vous les fournira. Il a même une implémentation de 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 des documents énormes

Vous devez lire les documents dont la taille est gigaoctets . Vous les obtenez peut-être de stdin, nourris par un autre processus. Ou vous les lisez à partir de gros fichiers. Ou peu importe. Le fait est que ce dont vous avez besoin est de not == avoir à lire tout le fichier en mémoire en une seule fois afin de le traiter.

Tu as choisi:

LibXML2

L'API de style SAX de Xerces fonctionnera dans cette capacité, mais LibXML2 est là parce qu'il est un peu plus facile de travailler avec. Une API de style SAX est une API Push: elle commence à analyser un flux et ne déclenche que les événements que vous devez capturer. Vous êtes obligé de gérer le contexte, l'état, etc. Le code qui lit une API de style SAX est beaucoup plus étendu qu'on pourrait l'espérer.

L'objet xmlReader de LibXML2 est une API d'extraction. Vous ask pour aller au prochain noeud ou élément XML; on ne te dit pas. Cela vous permet de stocker le contexte comme bon vous semble, de gérer différentes entités de manière beaucoup plus lisible dans le code que par toute une série de callbacks.

Des alternatives

Expat

Expat est un analyseur C++ bien connu qui utilise une API Pull-parser. Il a été écrit par James Clark.

Son statut actuel est actif. La version la plus récente est la 2.2.5, qui a été publiée le mois dernier (2017-10-31).

LlamaXML

C'est une implémentation d'une API de style StAX. C'est un extracteur, similaire à l'analyseur xmlReader de LibXML2.

Mais il n'a pas été mis à jour depuis 2005. Encore une fois, Caveat Emptor.

Support XPath

XPath est un système permettant d'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 à l'aide de propriétés communes, en utilisant une syntaxe normalisée. De nombreuses bibliothèques XML offrent un 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, il s’agit d’une API C, donc si cela vous dérange, il existe des alternatives.
  • PugiXML : Il est également livré avec le support XPath 1.0. Comme ci-dessus, il s’agit davantage d’une API C++ que de LibXML2. Vous serez donc peut-être plus à l’aise avec cela.
  • TinyXML : Il n’est pas fourni avec le support XPath, mais il existe le TinyXPath bibliothèque qui le fournit. TinyXML subit actuellement une conversion vers la version 2.0, qui modifie considérablement l'API. TinyXPath risque donc de ne pas fonctionner avec la nouvelle API. Comme TinyXML, TinyXPath est distribué sous la licence zLib.

Il suffit de faire le travail

Donc, vous ne vous souciez pas de la correction 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 récupère XML en mémoire et vous permet de le recoller sur le disque. Qu'est-ce que vous se soucie de l'API?.

Vous voulez un analyseur XML qui soit petit, facile à installer, simple à utiliser et suffisamment petit pour ne pas être pertinent pour la taille de votre éventuel exécutable.

Tu as choisi:

TinyXML

Je mets TinyXML dans cet emplacement car il s’agit d’une tâche 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 les attributs, etc.

L'écriture XML n'est pas un problème dans TinyXML. Il vous suffit de new monter quelques objets, de les attacher ensemble, d'envoyer le document à un std::ostream et tout le monde est content.

Il existe également un écosystème construit autour de TinyXML, avec une API plus conviviale pour les itérateurs, et même une implémentation de XPath 1.0 superposée.

TinyXML utilise la licence zLib, qui est plus ou moins la licence MIT avec un nom différent.

634
Nicol Bolas

Il existe une autre approche de la gestion du XML que vous pouvez envisager, appelée liaison XMLdata. Surtout si vous avez déjà une spécification formelle de votre vocabulaire XML, par exemple, dans XML Schema. 

La liaison de données XML vous permet d'utiliser XML sans effectuer d'analyse syntaxique XML ni de sérialisation. Un compilateur de liaisons de données génère automatiquement tout le code de bas niveau et présente les données analysées sous forme de classes C++ correspondant à votre domaine d'application. Vous travaillez ensuite avec ces données en appelant des fonctions et en utilisant des types C++ (int, double, etc.) au lieu de comparer des chaînes et d'analyser du texte (comme vous le feriez avec des API d'accès XML de bas niveau telles que DOM ou SAX).

Voir, par exemple, une implémentation de liaison de données XML open-source que j'ai écrite, CodeSynthesis XSD et, pour une version plus légère et sans dépendance,. CodeSynthesis XSD/e .

17
Boris Kolpackov

Dans Secured Globe , Inc., nous utilisons rapidxml . Nous avons essayé tous les autres, mais rapidxml semble être le meilleur choix pour nous. 

Voici un exemple:

 rapidxml::xml_document<char> doc;
    doc.parse<0>(xmlData);
    rapidxml::xml_node<char>* root = doc.first_node();

    rapidxml::xml_node<char>* node_account = 0;
    if (GetNodeByElementName(root, "Account", &node_account) == true)
    {
        rapidxml::xml_node<char>* node_default = 0;
        if (GetNodeByElementName(node_account, "default", &node_default) == true)
        {
            swprintf(result, 100, L"%hs", node_default->value());
            free(xmlData);
            return true;
        }
    }
    free(xmlData);
0
Michael Haephrati

Une autre remarque à propos d'Expat: cela vaut la peine de regarder pour le travail sur les systèmes embarqués. Cependant, la documentation que vous êtes susceptible de trouver sur le Web est ancienne et erronée. Le code source contient en fait des commentaires assez détaillés au niveau de la fonction, mais il leur faudra lire attentivement pour prendre du sens.

0
breakpoint

Mettez le mien aussi.

http://www.codeproject.com/Articles/998388/XMLplusplus-version-The-Cplusplus-update-of-y-XML

Aucune fonctionnalité de validation XML, mais rapide.

0
Michael

Alors ok. J'ai créé un nouveau, car aucune de la liste n'était conforme à mes besoins. 

Avantages:

  1. API de streaming Pull-parser de bas niveau ( Java StAX like )
  2. Exceptions et modes RTTI de supportés
  3. Limite d'utilisation de la mémoire, prise en charge des fichiers volumineux (testé avec 100 mib fichier XMark à partir de, la vitesse dépend du matériel)
  4. Prise en charge de UNICODE et détection automatique du codage de la source d'entrée 
  5. API de haut niveau pour la lecture de structures/POCO
  6. API de méta-programmation permettant d'écrire et de générer XSD à partir de structures/POCO Avec prise en charge de la structure xml (attributs et balises imbriquées) (la génération XSD nécessite RTTI, mais ne peut être utilisée qu'une seule fois lors du débogage)
  7. C++ 11 - GCC et VC++ 15+

Désavantages:

  1. Validation DTD et XSD non encore fournie 
  2. Obtention de XML/XSD par HTTP/HTTPS en cours, pas encore fait
  3. Nouvelle bibliothèque

Accueil du projet

0
Victor Gubin