パスワードを忘れた? アカウント作成
551812 journal

A7Mの日記: 覚え書き:libxml2のSAXの使い方 2

日記 by A7M
昨日の続き。

結局、パーサは使い慣れた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と仮想関数を使って各要素毎の処理を管理すれば何とかなるかな?

追記:
そういえば、今日はお休み。自宅でマターリ過ごすはずが、何でこんなことをやってしまったのだろう。>俺

この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。
typodupeerror

開いた括弧は必ず閉じる -- あるプログラマー

読み込み中...