以下のようにしてできました。
#include <vector> #include <boost/property_tree/ptree.hpp> #include <boost/property_tree/xml_parser.hpp> #include <boost/foreach.hpp> #define foreach BOOST_FOREACH struct Book { std::string title; std::string author; Book() {} Book(const Book& other) : title(other.title), author(other.author) {} Book(const std::string& title, const std::string& author) : title(title), author(author) {} }; void save(const std::string& filename) { std::vector<Book> books; books.reserve(2); books.push_back(Book("D&E", "Bjarne Stroustrup")); books.push_back(Book("MC++D", "Andrei, Alexandrescu")); using boost::property_tree::ptree; ptree pt; foreach (const Book& book, books) { ptree& child = pt.add("bookList.book", ""); child.put("<xmlattr>.title", book.title); child.put("<xmlattr>.author", book.author); } using namespace boost::property_tree::xml_parser; const int indent = 2; write_xml(filename, pt, std::locale(), xml_writer_make_settings(' ', indent, widen<char>("utf-8"))); } int main() { save("book.xml"); }
<?xml version="1.0" encoding="utf-8"?> <bookList> <book title="D&E" author="Bjarne Stroustrup"/> <book title="MC++D" author="Andrei Alexandrescu"/> </bookList>
write_xmlのところは、後ろの2引数を省略できますが、
writer settingsを設定しない場合、以下のように改行、インデントなしで出力されます。
<?xml version="1.0" encoding="utf-8"?> <bookList><book title="D&E" author="Bjarne Stroustrup"/><book title="MC++D" author="Andrei Alexandrescu"/></bookList>
ちなみにwriter settingsはアンドキュメントです。
write_xmlの第4引数に指定するxml_writer_settings型、
それを生成するヘルパ関数xml_writer_make_settings()が定義されています。
namespace boost { namespace property_tree { namespace xml_parser { ... template <class Ch> xml_writer_settings<Ch> xml_writer_make_settings(Ch indent_char = Ch(' '), typename std::basic_string<Ch>::size_type indent_count = 0, const std::basic_string<Ch> &encoding = widen<Ch>("utf-8")) { return xml_writer_settings<Ch>(indent_char, indent_count, encoding); } } } }
ついでに、さっき出力したXMLの読み込みはこんな感じです。
#include <iostream> #include <vector> #include <algorithm> #include <boost/property_tree/ptree.hpp> #include <boost/property_tree/xml_parser.hpp> #include <boost/foreach.hpp> #include <boost/mem_fn.hpp> #define foreach BOOST_FOREACH struct Book { std::string title; std::string author; Book() {} Book(const Book& other) : title(other.title), author(other.author) {} Book(const std::string& title, const std::string& author) : title(title), author(author) {} void print() const { std::cout << title << "," << author << std::endl; } }; void load(const std::string& filename) { using boost::property_tree::ptree; std::vector<Book> books; ptree pt; read_xml(filename, pt); foreach (const ptree::value_type& child_, pt.get_child("bookList")) { const ptree& child = child_.second; const std::string title = child.get<std::string>("<xmlattr>.title"); const std::string author = child.get<std::string>("<xmlattr>.author"); books.push_back(Book(title, author)); } std::for_each(books.begin(), books.end(), boost::mem_fn(&Book::print)); } int main() { load("book.xml"); }
D&E,Bjarne Stroustrup MC++D,Andrei Alexandrescu