documentを出力する
DOMの出力にはヘッダ:<rapidxml_print.hpp>に定義されたoperator<<あるいは関数:print()を使います。
#include <rapidxml.hpp>
#include <rapidxml_print.hpp>
#include <iostream>
#include <string>
#include <iterator>
using namespace std;
namespace rx = rapidxml;
int main() {
string xml = R"(<function include="<cstdio>"><return type="int"/>printf</function>)" "\0";
rx::xml_document<> doc;
doc.parse<0>(&xml[0]);
cout << "----- cout << doc\n";
cout << "[" << doc << "]\n";
}
いいカンジにタブ/改行を挿入してインデントをつけてくれてますが、このインデントが余計なお世話なこともあるでしょう。プロセス間通信なんかだと伝文長は極力短くしたいでしょうしね。関数:print()は出力先にイテレータまたはストリームが選べ、出力オプション:print_no_indentingを指定することでインデントを抑止できます。
#include <rapidxml.hpp>
#include <rapidxml_print.hpp>
#include <iostream>
#include <string>
#include <iterator>
using namespace std;
namespace rx = rapidxml;
int main() {
string xml = R"(<function include="<cstdio>"><return type="int"/>printf</function>)" "\0";
rx::xml_document<> doc;
doc.parse<0>(&xml[0]);
cout << "----- cout << doc\n";
cout << "[" << doc << "]\n";
cout << "----- print to stream\n";
cout << "["; rx::print(cout, doc); cout << "]\n";
cout << "----- print to stream (no-indenting)\n";
cout << "["; rx::print(cout, doc, rx::print_no_indenting); cout << "]\n";
cout << "----- print to iterator\n";
string str;
rx::print(back_inserter(str), doc);
cout << "[" << str << "]\n";
cout << "----- print to iterator (no-indenting)\n";
str.clear();
rx::print(back_inserter(str), doc, rx::print_no_indenting);
cout << "[" << str << "]\n";
}
以上がRapidXMLのざっくりとした解説。ノードを生成しDOMを組み上げるAPIも提供されています。allocate_node()/allocate_attribute()でノード/属性を生成しappend_node()/append_attribute()で組み立てるだけのシンプルなAPI、少々面倒ですが決して難しくはありません。
#include <rapidxml.hpp>
#include <rapidxml_print.hpp>
#include <iostream>
#include <string>
using namespace std;
namespace rx = rapidxml;
int main() {
/*
<function include="<cstdio>">
<return type="int"/>
printf
</function>
*/
rx::xml_document<> doc;
// <function>ノードにinclude属性を追加
rx::xml_node<>* fun_node = doc.allocate_node(rx::node_element, "function");
rx::xml_attribute<>* fun_attr = doc.allocate_attribute("include", "<cstdio>");
fun_node->append_attribute(fun_attr);
// <return>ノードにtype属性を追加
rx::xml_node<>* ret_node = doc.allocate_node(rx::node_element, "return");
rx::xml_attribute<>* ret_attr = doc.allocate_attribute("type", "int");
ret_node->append_attribute(ret_attr);
// <fuction>ノード下に<return>ノードとテキスト"printf"を追加
fun_node->append_node(ret_node);
fun_node->append_node(doc.allocate_node(rx::node_data, nullptr, "printf"));
// documentに<function>ノードを追加
doc.append_node(fun_node);
// んでもってプリント
cout << doc << endl;
}
ドキュメントによりますとRapidXMLの"売り"はその名のとおりの高速パースで、定番Apache Xerces-Cの50~100倍速いんだそうな。さほどの高機能を求めないならヘッダの#includeだけで使える高速軽量XMLパーサ、僕の"おどうぐばこ"がまたすこし大きくなりました。
