[iOS] NSXMLParser。SAXとDOMの比較とか

2012/07/22

こんにちは。きんくまです。

前回書いたNSXMLParserについてTNKさんからコメント欄で情報をいただきまして、調べてみました。

NSXMLParserはSAXパーサーで、DOMパーサーとは違うとのことです。
そういえば、使い方を調べたときにそんなことを書いてあったような。あんまり深く考えずに使ってました。

Wikiによると、SAX(Simple API for XML)はDOMに比べてこんな特徴があります。英語Wikiも参照

SAXには公式の仕様というものはないみたいです。

SAX DOM
DOMツリーを作らない DOMツリーを作る
イベントをベースにパース イベントベースでない
最小のメモリで済む
(DOMツリー全体を保持せず1部分だけを保持するから)
メモリが多く必要
(DOMツリー全体を保持するから)
速い 遅い
パース中に状態管理(特定のタグの中にいるとかいないとか)が必要 パース中は何もしないので状態管理はいらない
XMLが正しい形かどうかチェックできない(データを全て保持しないため) XMLが正しい形かチェックできる

表だけみるとSAXの方がいいことが多そうに見えますが、
イメージ的にはDOMを構築してる途中データがSAXでは取得される感じですね。

DOMはパースが終わればツリーが完成しているので、そのあとにDOMツリーをたどって中身にアクセスしてきます。
それに対してSAXはツリーを作らず、タグの開始 or 終了、文字をみつけたといったイベントのときに、その中身をプログラマが処理していく手動な感じです。

NSXMLParserがSAXタイプなのは、携帯端末がPCに比べて少ないメモリであるためでしょうね。

NSXMLParser

昨日の文字列が途中できれてイベントが発行される(1つのタグ内で複数回文字発見イベント発行)のは、もとからのようです。
さらに日本語とか英語とか関係なく、起こるようです。コメント欄でいただいたリンクです。

>> iPhone: NSXMLParser’s foundCharacters method called multiple time for single tag

なので、NSXMLParserでは
1. タグ開始イベントで文字列初期化
2. 文字見つけたよイベントで、保持してた文字と連結
3. 2が複数回に分けて起こる場合があるので繰り返して連結
4. タグ終了イベントで最終的に連結された文字列で何かする

という手順がデフォルトとなります。

教えていただいたAppleのデモでもそうなっていました。

昨日のコードを直すとこんな感じになります。

インスタンス変数は

    NSMutableString *_currentParsedCharacterData;
    BOOL _inElement;

実装部は

NSString *kXMLParseElementTag = @"ele";

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
    if ([elementName isEqualToString:kXMLParseElementTag]){
        _inElement = YES;
        [_currentParsedCharacterData setString:@""];
    }
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    if ([elementName isEqualToString:kXMLParseElementTag]){
        _inElement = NO;

        //_currentParsedCharacterDataを使って何かする
    }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    if (_inElement){
        [_currentParsedCharacterData appendString:string];
    }
}
LINEで送る
Pocket

自作iPhoneアプリ 好評発売中!
フォルメモ - シンプルなフォルダつきメモ帳
ジッピー電卓 - 消費税や割引もサクサク計算!

LINEスタンプ作りました!
毎日使える。とぼけたウサギ。LINEスタンプ販売中! 毎日使える。とぼけたウサギ

ページトップへ戻る