物置き

RapidXML試してみた

RapidXML - togeの日記
RapidXML 触ってみる - togeの日記
RapidXMLで辛い点 - togeの日記

こちらの記事でRapidXMLというライブラリの存在を知り、面白そうだと思ったのでちょっと試してみた。

まず配布元サイトのヘルプをおおばっぱにみた。下記のような特徴をもつ模様。

  • 1つのヘッダファイル(rapidxml.hpp)のみで利用できる。
  • テンプレートベースなので事前ビルド&リンク不要
  • Windowsでも*NIXでも動く
  • DOMだけ。SAXはない
  • Boostライセンス
  • 最速目指して作られていて超早いらしい
  • オンメモリの文字列データに対して処理するらしい

インストール

まずRapidXML配布元からファイルをダウンロードして適当なディレクトリに配置する。
現時点(2009-04-22時点)での最新版は1.12。
これを展開すると、4つのヘッダファイル(と2つのドキュメントファイル)が生成される。

  • rapidxml.hpp
  • rapidxml_iterators.hpp
  • rapidxml_print.hpp
  • rapidxml_utils.hpp

これらのうち、必要なのは主にrapidxml.hppのみ。
他はユーティリティ的なクラス群。
あとは、展開先ディレクトリをヘッダファイルの検索対象パスに追加するなり、
ファイルを組み込みたいプロジェクトのディレクトリに直接放り込むなりすればよい。

サンプルコード

こんな感じで使える。(ほとんどチュートリアルのコードそのまんま)

#include <iostream>
#include <string>
#include <rapidxml.hpp>

using namespace std;
using namespace rapidxml;

int main()
{
  // オンメモリのXMLデータ
  std::string data("<a><aa attr=\"&lt;value&gt;\">test</aa></a>");
  xml_document<> doc;
  try {
    doc.parse<0>((char*)data.c_str());
  }
  catch(parse_error& err) {
    cout << err.what() << " " << err.where<char*>();
    return 1;
  }

  for (xml_node<> *node  = doc.first_node(); node;node = node->next_sibling()) {
    cout << "ノード名: " << node->name() << "\n";
    for (xml_node<> *child  = node->first_node(); child;child = child->next_sibling()) {
      cout << "ノード名: " << child->name() << "\n";
      cout << "テキスト: " << child->value() << "\n";
      for (xml_attribute<> *attr = child->first_attribute();attr; attr = attr->next_attribute()) {
        cout << "属性名: " << attr->name() << " ";
        cout << "属性値: " << attr->value() << "\n";
      }
    }
  }
}
実行結果
ノード名: a
ノード名: aa
テキスト: test
属性名: attr 属性値: <value>

結構扱いやすい。
ちょっとした用途に使うなら、選択肢としてはかなり有力かもしれない。

DOMだけということで、どでかいXMLファイルの処理には向かないかも?
とはいえ、MSXMLはビルド環境に入っているバージョンの違いがトラブルの元になったことがあって
あまり好きじゃないというか、使わずに済むなら使いたくないので
DOMだけで済むなら、こちらの方が良さそうだと思った。


これはいいものを知った。
id:togeさんありがとうございます。