Boostを使用してXMLファイルを読み書きする良い方法(そして簡単な方法)はありますか?
Boostを使用してXMLファイルを読み取るための簡単なサンプルは見つかりません。 Boostを使用してXMLファイルの読み取りと書き込みを行う簡単なサンプルを教えてください。
Boostでない場合、推奨できるXMLファイルを読み書きするための優れたシンプルなライブラリはありますか? (C++ライブラリでなければなりません)
試してみてください pugixmlC++用の軽量でシンプルで高速なXMLパーサー
Pugixmlの最も良い点は、XPathサポートです。TinyXMLおよびRapidXMLにはありません。
RapidXMLの著者である「このプロジェクトのインスピレーションとなったpugixmlの研究についてArseny Kapoulkineに感謝したい」と「バージョン0.3に対してテストしたXMLパーサーであるpugixmlよりも5%-30%高速」最近バージョン0.42に達したpugixmlの。
Pugixmlドキュメントからの抜粋を次に示します。
主な機能は次のとおりです。
さて、あなたは尋ねるかもしれません-キャッチは何ですか?すべてがとてもかわいい-それは、XMLを解析するための小さく、高速で、堅牢で、クリーンなソリューションです。何が欠けている?わかりました、私たちは公正な開発者です-だからここに誤機能リストがあります:
TinyXML はおそらく良い選択です。 Boostの場合:
Boost Repository に Property_Tree ライブラリがあります。それは受け入れられましたが、現時点ではサポートが不足しているようです(編集: Property_Tree は今ではBoostの一部です バージョン1.41以降 、読んでください ドキュメント =そのXML機能に関して)。
Daniel Nufferは、Boost Spiritに xmlパーサー を実装しました。
Boostは RapidXML を使用します- chapterXML Parserof pageプロパティツリーを作成する方法 :
残念ながら、この記事の執筆時点では [〜#〜] xml [〜#〜] パーサーには Boost がありません。そのため、ライブラリには高速で小さな RapidXML パーサー(現在バージョン1.13)が含まれており、XML解析サポートを提供します。 RapidXMLはXML標準を完全にサポートしていません。 DTDを解析できないため、完全なエンティティ置換を行うことはできません。
XML boost tutorial も参照してください。
OPは "boostを使用してxmlファイルを読み書きする簡単な方法"を必要としているため、非常に基本的な例を以下に示します。
_<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>
_
(猫の名前は Matt Mahoneyのホームページ )
C++の対応する構造:
_struct Catowner
{
std::string owner;
std::set<std::string> cats;
};
_
read_xml()
使用法:
_#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()
使用法:
_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はXMLパーサーATMを提供しません。
Poco XML( Poco C++ libs の一部)は適切でシンプルです。
目的に十分であれば、ブーストシリアル化でXMLのアーカイブの読み取りと書き込みができるようです。
DefinatellyはTinyXMLを使用します*サムスアップ*
DOM機能のみを探している場合、このスレッドにはすでにいくつかの提案があります。私は個人的にはおそらくXPathサポートのないライブラリを気にしませんし、C++ではQtを使用します。 TinyXPathもあり、アラビカはXPathをサポートしていると主張していますが、それらについては何も言えません。
Arabica をご覧ください
Boostメーリングリストに潜んでいる私の経験から、XMLが主題として登場するたびに、それはUnicodeに関する議論に流用されているように見えます。ただし、現在、潜在的なUnicodeライブラリが間近に迫っているので、XMLライブラリがそこに表示されるのにそれほど時間がかかるとは思わない。
それまでの間、私もTinyXMLを使用しています。
RapidXMLに関する興味深いリンク。それを見てみましょう。
Boost.XMLの既存の提案を改善するためにGSoCが提案した作業があります: https://github.com/stefanseefeld/boost.xml しかしAndrzejとして提案されたBoost.PropertyTreeはこのタスクに適しています。自然に必要なxmlサイズと検証サポートに依存します。
Boostメーリングリストで最近提案されたライブラリもあります: http://www.codesynthesis.com/projects/libstudxml/doc/intro.xhtml
警告。 RapidXMLは大好きですが、UTF16を解析するときに非常に厄介なバグがあります。有効な値によってはクラッシュする場合があります。
Pugixmlをお勧めしたいのですが、名前空間のサポートが欠けているため、問題が発生する可能性があります。
Boost.spiritはどうですか?
ここ 、「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>
BOOSTを使用してXMLを簡単に読み取る方法があります。この例は、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");
}
};
}
属性を読み取ることは、もう少し複雑です。
-
参考のために:
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;
}