toge's diary

コンピュータ関連の趣味をつらつらと。

RapidXML 触ってみる2

うぬ、rapidxml.hppと一緒に提供されているrapidxml_utils.hppを使えばもっと簡単に書けたみたい。

#include <iostream>

#include "rapidxml_utils.hpp"

int
main(int argc, char* argv[]) {
  // check parameter
  if (argc < 2) {
    std::cerr << "usage : " << argv[0] << " <input file>" << std::endl;
    return 1;
  }

  // open file
  const char* filename = argv[1];
  rapidxml::file<> input(filename);

  // parse xml data
  rapidxml::xml_document<> doc;

  try {
    doc.parse<0>(input.data());
  }
  catch(rapidxml::parse_error& ex) {
    int position = (int)ex.where<char>() - (int)input.data();

    std::cerr << "parse error (" << position << ") : " << ex.what() << std::endl;
    return 1;
  }

  // traverse DOM tree
  std::cout << "name of first node is " << doc.first_node()->name() << std::endl;

  rapidxml::xml_node<>* node = doc.first_node("html");

  std::cout << "node <html> has value " << node->value() << std::endl;

  for (rapidxml::xml_attribute<>* attr = node->first_attribute(); attr; attr = attr->next_attribute()) {
    std::cout << "Node <html> has attirbute " << attr->name() << " ";
    std::cout << "with value " << attr->value() << std::endl;
  }

  for (rapidxml::xml_node<>* sibling = node->first_node(); sibling; sibling = sibling->next_sibling()) {
    std::cout << "Node <html> has sibling node " << sibling->name() << std::endl;
  }

  return 0;
}

rapidxml::fileが肝なんだけど、ちと使いづらいな。
コンストラクタでしかファイル名を指定できなくて、ファイルのオープンに失敗するとその中でstd::runtime_exception出しちゃうので、どうも扱いづらい。std::ifstreamみたいにファイルのオープンに成功・失敗のフラグがあればよいのに。