こんにちは。きんくまです。
前回書いた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]; } }
■ 自作iPhoneアプリ 好評発売中!
・フォルメモ - シンプルなフォルダつきメモ帳
・ジッピー電卓 - 消費税や割引もサクサク計算!
■ LINEスタンプ作りました!
毎日使える。とぼけたウサギ