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
