Gibt es eine gute Möglichkeit (und auch eine einfache Möglichkeit), mit Boost XML-Dateien zu lesen und zu schreiben?
Ich kann anscheinend kein einfaches Beispiel zum Lesen von XML-Dateien mit Boost finden. Können Sie mir ein einfaches Beispiel zeigen, in dem Boost zum Lesen und Schreiben von XML-Dateien verwendet wird?
Wenn nicht Boost, gibt es eine gute und einfache Bibliothek zum Lesen und Schreiben von XML-Dateien, die Sie empfehlen können? (es muss eine C++ Bibliothek sein)
Sie sollten versuchen pugixml Leichter, einfacher und schneller XML-Parser für C++
Das Schönste an pugixml ist die XPath Unterstützung, die TinyXML und RapidXML fehlt.
Zitat des RapidXML-Autors "Ich möchte Arseny Kapoulkine für seine Arbeit an Pugixml danken, die eine Inspiration für dieses Projekt war" und "5 bis 30% schneller als Pugixml, der schnellste mir bekannte XML-Parser". Er hatte gegen Version 0.3 getestet von Pugixml, die vor kurzem Version 0.42 erreicht hat.
Hier ist ein Auszug aus der pugixml-Dokumentation:
Die Hauptmerkmale sind:
Okay, könnten Sie fragen - was ist der Haken? Alles ist so süß - es ist eine kleine, schnelle, robuste und saubere Lösung zum Parsen von XML. Was fehlt? Ok, wir sind faire Entwickler - hier ist eine Liste mit Fehlfunktionen:
TinyXML ist wahrscheinlich eine gute Wahl. Was Boost angeht:
Es gibt die Property_Tree Bibliothek im Boost Repository . Es wurde akzeptiert, aber momentan scheint die Unterstützung zu fehlen (EDIT: Property_Tree ist jetzt Teil von Boost seit Version 1.41 , lies die Dokumentation = in Bezug auf seine XML-Funktionalität).
Daniel Nuffer hat einen xml-Parser für Boost Spirit implementiert.
Boost verwendet RapidXML wie in - beschrieben Kapitel XML-Parser der Seite So füllen Sie einen Eigenschaftsbaum aus :
Leider gibt es zum Zeitpunkt des Schreibens keinen XML Parser in Boost . Die Bibliothek enthält daher den Parser fast and tiny RapidXML (derzeit in Version 1.13), um XML-Parsing zu unterstützen. RapidXML unterstützt den XML-Standard nicht vollständig. Es ist nicht in der Lage, DTDs zu analysieren, und kann daher keine vollständige Entitätsersetzung durchführen.
Bitte beachten Sie auch das XML-Boost-Tutorial .
Da das OP eine "einfache Möglichkeit zum Verwenden von Boost zum Lesen und Schreiben von XML-Dateien" möchte, führe ich nachfolgend ein sehr einfaches Beispiel an:
<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>
(Katzennamen sind von Matt Mahoneys Homepage )
Die entsprechende Struktur in C++:
struct Catowner
{
std::string owner;
std::set<std::string> cats;
};
read_xml()
Verwendung:
#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()
Verwendung:
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 bietet keinen XML-Parser atm.
Poco XML (Teil der Poco C++ - Bibliotheken ) ist gut und einfach.
Nun, es gibt keine spezifische Bibliothek in Boost für XML-Parsing, aber es gibt viele Alternativen, hier ein paar: libxml , Xerces , Expat
Natürlich können Sie einige der anderen Bibliotheken in Boost verwenden, um Ihre eigene Bibliothek zu erstellen, aber das wird wahrscheinlich ein ziemliches Unterfangen sein.
Und hier ist ein ganzer Artikel zum Thema von IBM.
Es scheint, dass Boost-Serialisierung in XML aus Archiven lesen und in sie schreiben kann, wenn dies für Ihre Zwecke ausreicht.
Verwenden Sie auf jeden Fall TinyXML * Daumen hoch *
Wenn Sie nur nach DOM-Funktionen suchen, enthält dieser Thread bereits einige Vorschläge. Ich persönlich würde mich wahrscheinlich nicht mit einer Bibliothek ohne XPath-Unterstützung herumschlagen und in C++ Qt verwenden. Es gibt auch TinyXPath und Arabica behauptet, XPath-Unterstützung zu haben, aber dazu kann ich überhaupt nichts sagen.
Schauen Sie sich Arabica an
Aus meinen Erfahrungen in der Boost-Mailingliste geht hervor, dass jedes Mal, wenn XML als Betreff angezeigt wird, eine Diskussion über Unicode stattfindet. Da sich derzeit jedoch eine potenzielle Unicode-Bibliothek abzeichnet, wird es meiner Meinung nach nicht allzu lange dauern, bis eine XML-Bibliothek dort angezeigt wird.
In der Zwischenzeit habe auch ich TinyXML verwendet.
Interessanter Link zu RapidXML. Ich werde mir das mal ansehen.
Es gibt einen GSoC-Vorschlag zur Verbesserung des bestehenden Vorschlags von Boost.XML: https://github.com/stefanseefeld/boost.xml , aber wie Andrzej vorgeschlagen hat, ist Boost.PropertyTree für diese Aufgabe nett. Abhängig natürlich von der XML-Größe und der benötigten Validierungsunterstützung.
Es gibt auch eine Bibliothek, die kürzlich auf der Boost-Mailingliste vorgeschlagen wurde: http://www.codesynthesis.com/projects/libstudxml/doc/intro.xhtml
Eine Warnung. Ich liebe RapidXML, aber es hat einen sehr bösen Fehler beim Parsen von UTF16. Einige gültige Werte führen zum Absturz.
Ich würde gerne pugixml empfehlen - aber es fehlt die Namespace-Unterstützung, von der ich weiß, dass sie mir Probleme bereiten wird.
Was ist mit boost.spirit?
hier , sie zeigen einen " Mini XML " Parser
<?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>
Es gibt eine einfache Möglichkeit, XML mit BOOST zu lesen. Dieses Beispiel basiert auf 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");
}
};
}
Attribute zu lesen ist nur ein bisschen komplizierter.
-
Nur als referenz:
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;
}