Existe-t-il un bon moyen (et un moyen simple aussi) d'utiliser Boost pour lire et écrire des fichiers XML?
Je n'arrive pas à trouver d'exemple simple pour lire des fichiers XML à l'aide de Boost. Pouvez-vous me montrer un exemple simple qui utilise Boost pour lire et écrire des fichiers XML?
Sinon Boost, existe-t-il une bibliothèque simple et efficace pour lire et écrire des fichiers XML que vous pouvez recommander? (ce doit être une bibliothèque C++)
Vous devriez essayer pugixml Analyseur XML léger, simple et rapide pour C++
La meilleure chose à propos de pugixml est le support XPath , qui manque à TinyXML et RapidXML.
Citant l'auteur de RapidXML "Je voudrais remercier Arseny Kapoulkine pour son travail sur pugixml, qui a été une source d'inspiration pour ce projet" et "5% - 30% plus rapide que pugixml, l'analyseur XML le plus rapide que je connaisse" Il avait testé avec la version 0.3 de pugixml, qui a récemment atteint la version 0.42.
Voici un extrait de la documentation pugixml:
Les principales caractéristiques sont:
D'accord, vous pourriez demander - quel est le problème? Tout est si mignon - c'est une solution petite, rapide, robuste et propre pour analyser XML. Que manque-t-il? Ok, nous sommes des développeurs équitables - voici donc une liste de défauts:
TinyXML est probablement un bon choix. Quant à Boost:
Il y a la bibliothèque Property_Tree dans le Boost Repository . Il a été accepté, mais le support semble faire défaut pour le moment (EDIT: Property_Tree fait maintenant partie de Boost depuis la version 1.41 , lisez la documentation = concernant sa fonctionnalité XML).
Daniel Nuffer a implémenté un analyseur xml pour Boost Spirit.
Boost utilise RapidXML comme décrit dans - chapitre Analyseur XML de la page Comment remplir un arbre de propriétés :
Malheureusement, il n'y a pas XML analyseur dans Boost au moment de la rédaction de cet article. La bibliothèque contient donc l'analyseur rapide et minuscule RapidXML (actuellement dans la version 1.13) pour fournir un support d'analyse XML. RapidXML ne prend pas entièrement en charge la norme XML; il n'est pas capable d'analyser les DTD et ne peut donc pas effectuer de substitution d'entité complète.
Veuillez également vous référer au tutoriel de boost XML .
Comme l'OP veut un "moyen simple d'utiliser boost pour lire et écrire des fichiers xml", je fournis ci-dessous un exemple très basique:
<main>
<owner>Matt</owner>
<cats>
<cat>Scarface Max</cat>
<cat>Moose</cat>
<cat>Snowball</cat>
<cat>Powerball</cat>
<cat>Miss Pudge</cat>
<cat>Needlenose</cat>
<cat>Sweety Pie</cat>
<cat>Peacey</cat>
<cat>Funnyface</cat>
</cats>
</main>
(les noms de chats viennent de page d'accueil de Matt Mahoney )
La structure correspondante en C++:
struct Catowner
{
std::string owner;
std::set<std::string> cats;
};
read_xml()
utilisation:
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
Catowner load(const std::string &file)
{
boost::property_tree::ptree pt;
read_xml(file, pt);
Catowner co;
co.owner = pt.get<std::string>("main.owner");
BOOST_FOREACH(
boost::property_tree::ptree::value_type &v,
pt.get_child("main.cats"))
co.cats.insert(v.second.data());
return co;
}
write_xml()
utilisation:
void save(const Catowner &co, const std::string &file)
{
boost::property_tree::ptree pt;
pt.put("main.owner", co.owner);
BOOST_FOREACH(
const std::string &name, co.cats)
pt.add("main.cats.cat", name);
write_xml(file, pt);
}
Boost ne fournit pas d'atmosphère d'analyseur XML.
Poco XML (une partie des bibliothèques Poco C++ ) est bon et simple.
Eh bien, il n'y a pas de bibliothèque spécifique dans boost pour l'analyse XML, mais il existe de nombreuses alternatives, en voici quelques-unes: libxml , Xerces , Expat
Bien sûr, vous pouvez utiliser certaines des autres bibliothèques de boost pour vous aider à créer votre propre bibliothèque, mais ce sera probablement une entreprise.
Et voici n article entier sur le sujet par IBM.
Il semblerait que la sérialisation de boost puisse lire et écrire des archives en XML, si cela est suffisant pour vos besoins.
Définitivement utiliser TinyXML * pouce en l'air *
Si vous recherchez uniquement la fonctionnalité DOM, il y a déjà quelques suggestions dans ce fil. Personnellement, je ne m'embêterais probablement pas avec une bibliothèque sans support XPath, et en C++, j'utiliserais Qt. Il y a aussi TinyXPath, et Arabica prétend avoir le support XPath, mais je ne peux rien dire à ce sujet.
Jetez un oeil à Arabica
D'après mes expériences qui se cachent sur la liste de diffusion Boost, il apparaît que chaque fois que XML apparaît comme sujet, il est détourné vers une discussion sur Unicode. Cependant, étant donné qu'une bibliothèque Unicode potentielle se profile actuellement, je ne pense pas qu'il faudra trop de temps pour qu'une bibliothèque XML y apparaisse.
En attendant, moi aussi j'utilise TinyXML.
Lien intéressant sur RapidXML. Je vais y jeter un œil.
Il y a un travail proposé par le GSoC pour améliorer la proposition existante de Boost.XML: https://github.com/stefanseefeld/boost.xml mais comme Andrzej l'a proposé, Boost.PropertyTree est bien pour cette tâche. En fonction naturellement de la taille xml et du support de validation nécessaire.
Il y a aussi une bibliothèque qui a été récemment proposée sur la liste de diffusion Boost: http://www.codesynthesis.com/projects/libstudxml/doc/intro.xhtml
Un avertissement. J'adore RapidXML, mais il a un bug très méchant lors de l'analyse UTF16. Certaines valeurs valides le font planter.
J'adorerais recommander pugixml - mais il manque le support de l'espace de noms, ce qui, je le sais, va me poser des problèmes.
Et boost.spirit?
Ici , ils affichent un analyseur " Mini XML "
<?xml version="1.0"?>
<Settings>
<GroupA>
<One>4</One>
<Two>7</Two>
<Three>9</Three>
</GroupA>
<GroupA>
<One>454</One>
<Two>47</Two>
<Three>29</Three>
</GroupA>
<GroupB>
<A>String A</A>
<B>String B</B>
</GroupB>
</Settings>
Il existe un moyen simple de lire XML avec BOOST. Cet exemple est basé sur std :: wstring:
#include <string>
#include <boost/property_tree/xml_parser.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/foreach.hpp>
bool CMyClass::ReadXML(std::wstring &full_path)
{
using boost::property_tree::wptree;
// Populate tree structure pt:
wptree pt;
std::wstringstream ss; ss << load_text_file(full_path); // See below for ref.
read_xml(ss, pt);
// Traverse pt:
BOOST_FOREACH(wptree::value_type const& v, pt.get_child(L"Settings"))
{
if (v.first == L"GroupA")
{
unsigned int n1 = v.second.get<unsigned int>(L"One");
unsigned int n2 = v.second.get<unsigned int>(L"Two");
unsigned int n3= v.second.get<unsigned int>(L"Three");
}
else if (v.first == L"GroupB")
{
std::wstring wstrA = v.second.get<std::wstring>(L"A");
std::wstring wstrB = v.second.get<std::wstring>(L"B");
}
};
}
La lecture des attributs est un peu plus compliquée.
-
Juste pour la référence:
std::wstring load_text_file(std::wstring &full_path)
{
std::wifstream wif(full_path);
wif.seekg(0, std::ios::end);
buffer.resize(wif.tellg());
wif.seekg(0);
wif.read(buffer.data(), buffer.size());
return buffer;
}