C言語のlibxml2を使ってwebAPIのXMLを解析
apacheモジュール内でwebAPIを呼んでXMLを解析する必要があるため、C/C++で利用できるXMLパーサを調べてみた。
Cだと
- expat
- libxml2
C++だと
- tinyXml
- Xerces
などなど他にもさまざまなライブラリがあるようだが今回はlibxml2を使ってパースしてみる事とした。
XMLの知識に乏しいのと
C言語が苦手なのと
ライブラリのAPIが多すぎて
などが重なってかなり苦戦しました。
でもXpathが使えるのは便利だなあと思った。
こちらの方のコードを参考に作らせていただきました。
yahoo!掲示板のRSSのitem要素を出力するだけのプログラム
#include <stdio.h> #include <libxml/xmlreader.h> #include <libxml/xpath.h> enum Status { Success = 0, Fail = -1, }; const char* REQUEST_API = "http://messages.yahoo.co.jp/bbs?action=4&board=552019556&sid=552019556&tid=kcc08bc0obafb3u"; const char* XPATH_ITEM = "/rss//item/*/text()"; // item以下全てのXPATH const char* XPATH_TITLE = "/rss//item/title/text()"; // titleのXPATH const char* XPATH_PUB_DATE = "/rss//item/pubDate/text()"; // pubDateのXPATH int main(void) { xmlTextReaderPtr reader = xmlNewTextReaderFilename(REQUEST_API); if (!reader) return Fail; xmlTextReaderRead(reader); xmlTextReaderExpand(reader); xmlDocPtr doc = xmlTextReaderCurrentDoc(reader); if (!doc) return Fail; xmlXPathContextPtr ctx = xmlXPathNewContext(doc); if (!ctx) return Fail; xmlXPathObjectPtr xpobj = xmlXPathEvalExpression((xmlChar *)XPATH_ITEM, ctx); if (!xpobj) return Fail; xmlNodeSetPtr nodes = xpobj->nodesetval; int size = (nodes) ? nodes->nodeNr : 0; for (int i = 0; i < size; ++i) { if (!xmlXPathNodeSetIsEmpty(nodes)) { xmlNodePtr node = xmlXPathNodeSetItem(nodes, i); if (node->content) { printf("%s => %s\n", node->parent->name, node->content); } else { printf("invalid node\n"); return Fail; } } } xmlXPathFreeObject(xpobj); xmlXPathFreeContext(ctx); xmlFreeDoc(doc); xmlFreeTextReader(reader); xmlCleanupParser(); return Success; }
追記(20090322)
xmlDocPtrを取得するために以下のようにやっていましたが
xmlTextReaderPtr reader = xmlNewTextReaderFilename(REQUEST_API); if (!reader) return Fail; xmlTextReaderRead(reader); xmlTextReaderExpand(reader); xmlDocPtr doc = xmlTextReaderCurrentDoc(reader);
本家サンプルを見るとこれだけで取れるみたい。
xmlDocPtr doc = xmlParseFile(REQUEST_API);
総括
phpのXML系extensionやperlのXSのXML::LibXMLのソースコードを読んだほうがlibxml2を理解できるのかもしれない。
こういう処理はLLに比べてどれだけ早いのかベンチとってみたい。