SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

高速軽量XMLパーサ:RapidXMLを触ってみた

documentを出力する

 DOMの出力にはヘッダ:<rapidxml_print.hpp>に定義されたoperator<<あるいは関数:print()を使います。

list-09
#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";
}
fig-08
fig-08

 いいカンジにタブ/改行を挿入してインデントをつけてくれてますが、このインデントが余計なお世話なこともあるでしょう。プロセス間通信なんかだと伝文長は極力短くしたいでしょうしね。関数:print()は出力先にイテレータまたはストリームが選べ、出力オプション:print_no_indentingを指定することでインデントを抑止できます。

list-10 print.cpp
#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";

}
fig-09
fig-09

 以上がRapidXMLのざっくりとした解説。ノードを生成しDOMを組み上げるAPIも提供されています。allocate_node()/allocate_attribute()でノード/属性を生成しappend_node()/append_attribute()で組み立てるだけのシンプルなAPI、少々面倒ですが決して難しくはありません。

list-11 build_xml.cpp
#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;
}
fig-10
fig-10

 ドキュメントによりますとRapidXMLの"売り"はその名のとおりの高速パースで、定番Apache Xerces-Cの50~100倍速いんだそうな。さほどの高機能を求めないならヘッダの#includeだけで使える高速軽量XMLパーサ、僕の"おどうぐばこ"がまたすこし大きくなりました。

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
特集記事連載記事一覧

もっと読む

この記事の著者

επιστημη(エピステーメー)

C++に首まで浸かったプログラマ。Microsoft MVP, Visual C++ (2004.01~2018.06) "だった"りわんくま同盟でたまにセッションスピーカやったり中国茶淹れてにわか茶...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/10235 2017/07/26 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー