ぷろぐ((>ω<))

ぷろぐらみんぐ関係のメモ

boostでXMLの読み書き

boostを使ったXML読み書きのサンプル。

参考:
https://sites.google.com/site/boostjp/tips/xml
http://stackoverflow.com/questions/6656380/boost-1-46-1-property-tree-how-to-iterate-through-ptree-receiving-sub-ptrees

こんな感じのサンプルXMLを読み書きします。

<?xml version="1.0" encoding="utf-8"?>
<parent>
  <children>
    <child type="age">3</child>
    <child type="age">5</child>
    <child type="age">7</child>
    <child type="age">12</child>
  </children>
</parent>

ソースコード

#include <iostream>
#include <vector>
#include <iterator>
#include <string>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <boost/foreach.hpp>
#include <boost/lexical_cast.hpp>

struct Child {
	int age;
	Child() : age(0) {}
	Child(int a) : age(a) {}
};

struct Parent {
	std::vector<Child> children;
	inline void init() { children.clear(); }
	inline void addChild(int age) { children.push_back(Child(age)); }
	void describe() {
		std::cout << "--- Describe begin --\n";
		for(std::vector<Child>::const_iterator cit = children.begin(); cit != children.end(); cit++)
			std::cout << cit->age << std::endl;
		std::cout << "--- Describe end --\n";
	}
};

void save(const std::string &xml_file, const Parent &parent) {
	boost::property_tree::ptree pt_parent;
	for(std::vector<Child>::const_iterator cit = parent.children.begin(); cit != parent.children.end(); cit++) {
		boost::property_tree::ptree &pt_child = pt_parent.add("parent.children.child", cit->age);
		pt_child.put("<xmlattr>.type", "age");
	}
	boost::property_tree::write_xml(xml_file, pt_parent, std::locale(), boost::property_tree::xml_writer_make_settings(' ', 2, boost::property_tree::detail::widen<char>("utf-8")));
}

void load(const std::string &xml_file, Parent &parent) {
	parent.init();
	boost::property_tree::ptree pt_parent;
	boost::property_tree::read_xml(xml_file, pt_parent);
	BOOST_FOREACH(const boost::property_tree::ptree::value_type &v, pt_parent.get_child("parent.children")) {
		// v.first is the name of the child.
		// v.second is the child tree.
		const boost::property_tree::ptree &pt_child = v.second;
		if (boost::optional<int> age = pt_child.get_optional<int>("")) {
			parent.addChild(age.get());
		}
	}
}

void main() {
	std::string xml_file("test.xml");
	Parent parent1;
	parent1.addChild(3);
	parent1.addChild(5);
	parent1.addChild(7);
	parent1.addChild(12);

	parent1.describe();
	save(xml_file, parent1);

	Parent parent2;
	load(xml_file, parent2);
	parent2.describe();

	std::system("pause");
	return;
}