Boost.PropertyTree でXMLを読書き

Boost C++ Libraries 1.41.0 にて、PropertyTreeライブラリが追加されました。
カテゴリとしては、std::vectorやstd::mapのように、データ構造を提供するライブラリで、PropertyTreeが提供するのは"ツリー構造"です。
また、XML,JSON,INI,INFO Parserが付属されています。



試しにXMLを、PropertyTreeのXML Parserで解析してみます。


目指すところとしては、↓こんな感じのXMLを読んで、

<planet>
    <name>mars</name>
    <equatorial_axis>3396</equatorial_axis>
    <satellites>
        <satellite>phobos</satellite>
        <satellite>deimos</satellite>
    </satellites>
</planet>

次のように出力したいと思います。

名称: mars
赤道半径: 3396km
衛星: phobos
衛星: deimos

まず、扱いたいXMLと同じデータ構造のクラスを用意します。

#if !defined PLANET_HPP
#define PLANET_HPP

#include <string>
#include <vector>

// 惑星クラス
struct planet
{
    std::string name; // 名称
    int equatorial_axis; // 赤道半径
    std::vector<std::string> satellites; // 衛星の動的配列

    planet() : equatorial_axis() {}
};

#endif // PLANET_HPP

XML Parser を使ってXMLをplanetクラスに変換し、確認用に出力するコードを書きます。

#include <iostream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <boost/foreach.hpp>
#include "planet.hpp" // さっきつくったクラス

#define foreach BOOST_FOREACH

using namespace std;

// ptree型変数にXMLを読み込み、各メンバをptree::getで取得していく
planet read(const std::string& filename)
{
    boost::property_tree::ptree tree;
    boost::property_tree::read_xml(filename, tree);

    planet result;
    result.name = tree.get<std::string>("planet.name");
    result.equatorial_axis = tree.get<int>("planet.equatorial_axis");
    foreach (const boost::property_tree::ptree::value_type& satellite,
        tree.get_child("planet.satellites"))
    {
        result.satellites.push_back(satellite.second.data());
    }
    return result;
}

// XMLを読んで、内容をコンソールに出力する
int main()
{
    const planet mars = read("mars.xml");

    cout << "名称: " << mars.name << endl;
    cout << "赤道半径: " << mars.equatorial_axis << "km" << endl;
    foreach (const string& satellite, mars.satellites)
    {
        cout << "衛星: " << satellite << endl;
    }

    return 0;
}

これを実行すると…。

名称: mars
赤道半径: 3396km
衛星: phobos
衛星: deimos

最初に提示した結果を得ることができました。



今までBoost.SerializationでXMLの読書きをしていた処理を、今後はPropertyTreeのXML Parserでやろうかとか考えてます。