iOSアプリでXMLを解析する方法(NSXMLParser)【基礎編】

今回はiOSアプリでXMLをNSXMLParserを使用して解析する方法を紹介する。
NSXMLParserは「libxml2.dylib」を必要とするので、プロジェクトに追加しておくこと。


最初にNSXMLParserの主なデリゲートメソッドを紹介しておく。
これらのデリゲートメソッドを使用し、XMLから必要な情報を取得する。

//解析開始時
parserDidStartDocument:

//要素の開始タグを読み込んだ時
parser: didStartElement: namespaceURI: qualifiedName: attributes:

//タグ以外のテキストを読み込んだ時
parser: foundCharacters:

//要素の終了タグを読み込んだ時
parser: didEndElement: namespaceURI: qualifiedName:

//解析終了時
parserDidEndDocument:

//エラー発生時
parser: parseErrorOccurred:


XMLデータがNSDataの場合:

NSXMLParser *parser = [[NSXMLParser alloc] initWithData:<XMLデータ(NSData型)>];

XMLデータがファイルの場合:

NSURL *url = [NSURL fileURLWithPath:<XMLデータのファイルパス>];
NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:url];

<実装例>
下記のxmlデータから「count」の値を取得するサンプルコードを示す。

<users>
  <count>2</count>
  <timestamp>2014/11/10 19:20:21.123</timestamp>
  <user>
    <name>Taro</name>
  </user>
  <user>
    <name>Hanako</name>
  </user>
</users>

ソースコード

#import "XmlParse.h"

@implementation XmlParse

NSString *result;

BOOL isTarget;

-(void) doParse{
    
    //解析対象となるXMLを作成
    NSString *strXml = @"<users><count>2</count><timestamp>2014/11/10 19:20:21.123</timestamp><user><name>Taro</name></user><user><name>Hanako</name></user></users>";
    
    //NSData型に変換
    NSData *dataXml = [strXml dataUsingEncoding:NSUTF8StringEncoding];
    
    //NSXMLParser初期化
    NSXMLParser *parser = [[NSXMLParser alloc] initWithData:dataXml];
    
    //デリゲートの設定
    parser.delegate = self;
    
    //解析開始
    [parser parse];
}

//デリゲートメソッド(解析開始時)
-(void) parserDidStartDocument:(NSXMLParser *)parser{

    NSLog(@"解析開始");
    
    //解析の初期化処理
    isTarget = NO;
}

//デリゲートメソッド(要素の開始タグを読み込んだ時)
- (void) parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
   namespaceURI:(NSString *)namespaceURI
  qualifiedName:(NSString *)qName
     attributes:(NSDictionary *)attributeDict{
    
     NSLog(@"要素の開始タグを読み込んだ:%@",elementName);
    
    if([elementName isEqualToString:@"count"]){
        
        isTarget = YES;     //データを取得するターゲットである事を保持する
    }
    
}

//デリゲートメソッド(タグ以外のテキストを読み込んだ時)
- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
    
    NSLog(@"タグ以外のテキストを読み込んだ:%@", string);
    
    if(isTarget){           //データを取得するターゲットの場合

        result = string;   //読み込んだテキストを取得結果として保持する
    }
}

//デリゲートメソッド(要素の終了タグを読み込んだ時)
- (void) parser:(NSXMLParser *)parser
  didEndElement:(NSString *)elementName
   namespaceURI:(NSString *)namespaceURI
  qualifiedName:(NSString *)qName{
    
    NSLog(@"要素の終了タグを読み込んだ:%@",elementName);
    
    isTarget = NO;
}

//デリゲートメソッド(解析終了時)
-(void) parserDidEndDocument:(NSXMLParser *)parser{
    
    NSLog(@"解析終了");
    
    [self dispResult];
}

//結果の表示
-(void) dispResult{
    
    NSLog(@"解析結果 countの値:%@",result);
}

@end

実行結果

2014-11-10 22:48:07.170 XmlSample[16477:110619] 解析開始
2014-11-10 22:48:07.171 XmlSample[16477:110619] 要素の開始タグを読み込んだ:users
2014-11-10 22:48:07.171 XmlSample[16477:110619] 要素の開始タグを読み込んだ:count
2014-11-10 22:48:07.172 XmlSample[16477:110619] タグ以外のテキストを読み込んだ:2
2014-11-10 22:48:07.172 XmlSample[16477:110619] 要素の終了タグを読み込んだ:count
2014-11-10 22:48:07.172 XmlSample[16477:110619] 要素の開始タグを読み込んだ:timestamp
2014-11-10 22:48:07.172 XmlSample[16477:110619] タグ以外のテキストを読み込んだ:2014/11/10 19:20:21.123
2014-11-10 22:48:07.173 XmlSample[16477:110619] 要素の終了タグを読み込んだ:timestamp
2014-11-10 22:48:07.173 XmlSample[16477:110619] 要素の開始タグを読み込んだ:user
2014-11-10 22:48:07.173 XmlSample[16477:110619] 要素の開始タグを読み込んだ:name
2014-11-10 22:48:07.173 XmlSample[16477:110619] タグ以外のテキストを読み込んだ:Taro
2014-11-10 22:48:07.173 XmlSample[16477:110619] 要素の終了タグを読み込んだ:name
2014-11-10 22:48:07.173 XmlSample[16477:110619] 要素の終了タグを読み込んだ:user
2014-11-10 22:48:07.174 XmlSample[16477:110619] 要素の開始タグを読み込んだ:user
2014-11-10 22:48:07.176 XmlSample[16477:110619] 要素の開始タグを読み込んだ:name
2014-11-10 22:48:07.176 XmlSample[16477:110619] タグ以外のテキストを読み込んだ:Hanako
2014-11-10 22:48:07.176 XmlSample[16477:110619] 要素の終了タグを読み込んだ:name
2014-11-10 22:48:07.177 XmlSample[16477:110619] 要素の終了タグを読み込んだ:user
2014-11-10 22:48:07.177 XmlSample[16477:110619] 要素の終了タグを読み込んだ:users
2014-11-10 22:48:07.177 XmlSample[16477:110619] 解析終了
2014-11-10 22:48:07.177 XmlSample[16477:110619] 解析結果 countの値:2

実行結果の最後の行に取得した「count」タグの値が表示されている。

Enjoy Programing!!

<関連記事>
iOSアプリでXMLを解析する方法(NSXMLParser)【基礎編】(本記事)
iOSアプリでXMLを解析する方法(NSXMLParser)【性能向上編】

<お勧め書籍>

詳解 Objective-C 2.0 第3版
iOSアプリ開発技術者として仕事をするのであれば、必ず読んでおくべき書籍である。
筆者も何度も繰り返し精読している。