株式会社ブリッジ・メタウェア
(株)ブリッジ・メタウェアの社員ブログです。
開発していく中での発見や情報を発信していきます!

今回はiPhone/iPadアプリ内でXMLをパースする方法について書いてみます。
私の場合、iPhone/iPadでXML形式のデータを扱うのは主に以下のケースです。

  1. iPhone/iPad内に保存されたアプリ独自のデータを読込みする場合
  2. サーバ(Servlet)と通信する場合

まずはDOMでいくか、SAXでいくか選択します。小さいデータならDOMが扱いやすいので、普通にDOM形式で読みこんでしまいます。
問題になるのは、ちょっと大きめのデータを扱う場合で、DOM形式で読みこんでから自分のオブジェクトに変換したのでは一時的に多くのメモリを必要としてしまいます。読込しながら自分のオブジェクトに変換していきたいところですから、定石どおりSAXを利用することにします。
SAXを利用する場合はNSXMLParserを使うか、libxmlを使うか、の二つの選択肢が標準的に用意されています。NSXMLParserは使いやすく、libxmlは高速である、との情報がありました。もちろん高速な方(libxml)を選択しますよ!

SAXはXMLの構文解析をしながら、適切なメソドを呼び出してくれますので、我々はイベントハンドラの登録と、イベントハンドラの実装を行います。

// タグを読み込んだら呼び出されます。
static void startElementHandler(void* ctx,
					const xmlChar* localname,
					const xmlChar* prefix,
					const xmlChar* URI,
					int nb_namespaces,
					const xmlChar** namespaces,
					int nb_attributes,
					int nb_defaulted,
					const xmlChar**attributes);

// タグが閉じられたら呼び出されます。
static void	endElementHandler(void* ctx,
					const xmlChar* localname,
					const xmlChar* prefix,
					const xmlChar* uri);

// 文字列を読み込んだら呼び出されます。
static void charactersFoundHandler(void* ctx, const xmlChar* ch, int len);

それぞれのハンドラではタグ名等に応じて独自形式のオブジェクトを作成し、設定していけば良いのですが、startElementHandlerでElementから属性値を取得するのがとても面倒です。速い方を選択した代償だと思って頑張りましょう!以下にその方法を抜粋して記述します。

	if (nb_attributes > 0) {
		NSMutableDictionary *attributes = [[[NSMutableDictionary alloc]init]autorelease];
		for (int i = 0; i < nb_attributes; i++) {
			NSString *key = [NSString stringWithCString:(const char*)charAttributes[0] encoding:NSUTF8StringEncoding];
			int length = charAttributes[4] - charAttributes[3];
			NSString *val = [[NSString alloc]initWithBytes:charAttributes[3] length:length encoding:NSUTF8StringEncoding];
			[attributes setObject:val forKey:key];
			charAttributes += 5;
		}
		// TODO: ここでオブジェクトに属性(attributes)をセットして下さい。
	}

MAGICナンバーも出てきますけど、最近はあんまり気を使わなくなりました。番号が直接書いてあるほうが良い場合もあるということにしましょう。

これで大抵のXML要素のパースが可能になりました。

|trackbacks(4) |22:03 2010/11/01
トラックバック
この記事へのトラックバックURL

Tweetback from SIHO

今度TBXMLと速度比較しよう。XMLのパースは早いに越したことは無いもの。 iPhone/iPadアプリでのXMLパース « BridgeMetaware http://p.tl/-8qf

at 13:11 2011/06/21
Tweetback from vio7j

iPhone/iPadアプリでのXMLパース « BridgeMetaware: 今回はiPhone/iPadアプリ内でXMLをパースする方法について書いてみます。 私の場合、iPhone/iPadでXML形式のデータを扱… http://bit.ly/eva3E5

at 11:37 2010/11/28
Tweetback from わかめニュース(プログラミング)

iPhone/iPadアプリでのXMLパース « BridgeMetaware http://bit.ly/eUiGw0

at 11:30 2010/11/28
Tweetback from ブリッジ・メタウェア

【ブログ更新】 iPhone/iPadアプリでのXMLパース – 今回はiPhone/iPadアプリ内でXMLをパースする方法について書いてみます。私の場合、iPhone/iPadでXML形式のデータを扱うのは主に以下のケースで… http://wp.me/p18NTR-6B

at 13:03 2010/11/01
ENTRY
  • UIBezierPathの描画で注意するべきこと
  • iPhone4でVGA出力
  • iPhoneアプリ審査落ち
  • OpenGLで省電力
  • iPhone/iPadアプリでのXMLパース
  • 実機で画像が表示されない
  • iPhone/iPadクライアントとサーバ間通信
  • バージョンアップ承認
  • アプリ更新
  • IBを使わない開発
  • CATEGORY
  • iPhone/iPad開発 (9)
  • Objective-C (2)
  • OpenGL (1)
  • その他 (1)
  • コラム (2)
  • 技術情報 (5)
  • 未分類 (2)
  • 製品情報 (2)
  • ARCHIVE
  • 2010年11月 (6)
  • 2010年10月 (5)
  • RECENT TRACKBACKS
  • 2011/7/12 OpenGLで省電力 « BridgeM...
  • 2011/6/21 今度TBXMLと速度比較し...
  • 2010/12/4 [iPhoneSDK] / UIBezierPathの...
  • 2010/12/2 アンチエイリアスが有...
  • 2010/11/28 iPhone/iPadアプリでのXML...

  • BM ON FACE BOOK
    Copyright © 2011 Bridge Metaware Co., Ltd. All Rights Reserved.