A7Mの日記: 覚え書き:libxml2のSAXの使い方 2
結局、パーサは使い慣れたlibxml2。libxml2はDOMしか使っていなかったけど、SAXだとこんな感じ。
#include <libxml/SAX.h>
#include <string.h>
void OnStartElement(void* ctx, const xmlChar* name, const xmlChar** atts);
void OnEndElement(void * ctx, const xmlChar * name);
void OnCharacters(void* ctx, const xmlChar * ch, int len);
void OnStartDocument(void * ctx);
void OnEndDocument(void * ctx);
int main(int argc, char* argv[])
{
xmlSAXHandler SAXHander;
memset(&SAXHander, 0, sizeof(xmlSAXHandler));
SAXHander.startDocument = OnStartDocument;
SAXHander.endDocument = OnEndDocument;
SAXHander.startElement = OnStartElement;
SAXHander.endElement = OnEndElement;
SAXHander.characters = OnCharacters;
xmlSAXUserParseFile(&SAXHander, NULL, "hoge.xml");
return 0;
}
void OnStartDocument(void * ctx)
{
}
void OnEndDocument(void * ctx)
{
}
void OnStartElement(void* ctx, const xmlChar* name, const xmlChar** atts)
{
}
void OnEndElement(void * ctx, const xmlChar * name)
{
}
void OnCharacters(void* ctx, const xmlChar * ch, int len)
{
}
イベントハンドラはxmlSAXHandlerのそれぞれのメンバに関数ポインタを渡してやればOK。
文書の開始、終了はstartDocument/endDocument、
要素の開始、終了はstartElement/endElement、
テキスト部分はcharacters。
文字列はUTF-8で来るから、iconvなどを使ってSJISやEUCに変換してやる。
startElementのattsには要素の属性が来る。
配列の偶数(0,2,4…)は要素名。奇数(1,3,4…)はその値。値がNULLならば終わり。
charactersに渡ってくる文字列は'\0'で終わっていないので、必ず文字列長を使って管理すること。
やっぱり、SAXはイベントドリブン形式だけあって要素毎の処理の管理だけでも('A`)マンドクセ
std::stackと仮想関数を使って各要素毎の処理を管理すれば何とかなるかな?
追記:
そういえば、今日はお休み。自宅でマターリ過ごすはずが、何でこんなことをやってしまったのだろう。>俺
libxml2なら (スコア:0)
Re:libxml2なら (スコア:1)
これ、ノードを取り出して、それをDOMで処理できますね・・・。
こっちのほうがいいかもしれません。ありがとうございます。