iOS XMLパース

ネットワークに関連して, よく利用されるXMLのデータを扱う方法として
iOSでXMLを簡単にパースする方法のサンプルをのせます。

手順

iOSには, NSXMLParserというくらすと,XMLの各パーツを処理するためのコードの実装である, NSXMLParserDelegateを利用します。

iOSでは他にも3rd PartyのXMLパースライブラリがあるようです。簡単な用途であれば, このNSXMLParserで十分だとは思います。

NSXMLParserDelegate

サンプルで利用するメソッド意外にもOverrideできるものはあります。
詳しくは, Appleのドキュメントにあります。

アーキテクチャ

個人的には, サンプルのように一つのクラスに, パースするクラスと, NSXMLParserDelegateの実装を入れて, 外部よりデータを渡すというスタイルがいいのかなと思っています。
そして, 1つのXMLの処理に対して1つのクラスを準備するかなというところです。

サンプル

ヘッダ XMLSample.h

@interface XMLSample : NSObject<NSXMLParserDelegate>

-(void)parseStr:(NSString *)body;
-(void)parseData:(NSData *) data;

@end

コード XMLSample.m

@implementation XMLSample

#pragma mark - Entry Point
-(void)parseStr:(NSString *)body {
    [self parseData:[body dataUsingEncoding:NSUTF8StringEncoding]];
}

-(void)parseData:(NSData *) data{
    NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
    parser.delegate = self;
    [parser parse];
}

// Not required these are options

#pragma mark -
#pragma mark - Delegate
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
    
    if ( [elementName isEqualToString:@"movies"] ) {
        NSLog(@"movies");
    }
    else if ( [elementName isEqualToString:@"movie"] ) {
        NSString *title = (NSString *)[attributeDict objectForKey:@"title"];
        NSLog(@"Title %@", title);
    }
}

-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    // End element
}

-(void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
    // Error was found
    NSLog(@"Parse Error %@", [parseError localizedDescription]);
}
@end

Entry Pointと書いているところが, パースを実行している部分で, Delegate以降が実際の処理です。
今回は簡単なXMLで要素を見つけて属性をとるといったものになっています。
もし, XMLが正しくない形式だと, エラーの部分のコードにうつります。

利用方法およびテスト

実際にテストデータは以下です。

<?xml version="1.0"?>
<movies><movie title="Titanic" />
<movie title="Attack of titan" />
</movies>

テストコードです

// XML Sample
NSString *str = @"<?xml version=\"1.0\"?><movies><movie title=\"Titanic\" /><movie title=\"Attack of titan\" /></movies>";
    
XMLSample *parser = [[XMLSample alloc] init];
[parser parseStr:str];

実行した結果です。

movies
Title Titanic
itle Attack of titan