読者です 読者をやめる 読者になる 読者になる

iPhoneアプリ作るためにXMLのパースをしたくて勉強

iPhone Objective-C GDataXMLNode

iPhoneアプリを作ってみたいと思い、手探りで勉強をはじめだしたところ。
とりあえずRSSのパースからやってみようと思ったら速攻でハマったのでメモメモ。

前提

ハマった所

  • そのままやったのに空データが返って来てムキャー!ってなった

結論

ハマった流れ

NSArray* titleList = [rootNode nodesForXPath:@"//title" error:&error];
NSLog(@"%@", titleList);   // titleリストが出てくれますように。
  • でもなぜか以下のようなログになってタイトルが取ってこられない
2010-01-15 22:46:10.496 samplePrj[43007:20b] (
)
  • 「そういえば昔何かでパースしようとした時にnamespaceでハマったな。それかな?」と思い、「GDataXMLNode nodeForXPath」でググった
  • そしたらソースにたどり着きまして、以下のようなオーバーロードのメソッドを見つける
- (NSArray *)nodesForXPath:(NSString *)xpath
                namespaces:(NSDictionary *)namespaces
                     error:(NSError **)error {

Google Readerからのレスポンスを見てみるとルートのfeedエレメントにはnamespaceをたくさん指定しています。こんな感じです。

<feed xmlns:idx="urn:atom-extension:indexing" xmlns:gr="http://www.google.com/schemas/reader/atom/" xmlns:media="http://search.yahoo.com/mrss/" xmlns="http://www.w3.org/2005/Atom" idx:index="no">

なのでこれらをルートエレメントに教えてやる。

[root addNamespace:[DDXMLNode namespaceWithName:@"idx" stringValue:@"urn:atom-extension:indexing"]];
[root addNamespace:[DDXMLNode namespaceWithName:@"gr" stringValue:@"http://www.google.com/schemas/reader/atom/"]];
[root addNamespace:[DDXMLNode namespaceWithName:@"media" stringValue:@"http://search.yahoo.com/mrss/"]];
[root addNamespace:[DDXMLNode namespaceWithName:@"foo" stringValue:@"http://www.w3.org/2005/Atom"]];

これで取り出す準備完了。defaultのnamespaceであるhttp://www.w3.org/2005/Atomには適当にfooという名前を付けた。

  • 「ほうほう。rdf:RDFタグのxmlnsの後ろ部分を全部つっこめばいいんだな?」となり、コードを以下のように修正
NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:
                        @"http://purl.org/rss/1.0/",                     @"foo",
                        @"http://www.w3.org/1999/02/22-rdf-syntax-ns#",  @"rdf",
                        @"http://purl.org/rss/1.0/modules/taxonomy/",    @"taxo",
                        @"http://purl.org/rss/1.0/modules/syndication/", @"sy",
                        @"http://purl.org/dc/elements/1.1/",             @"dc",
                     nil];

NSArray* titleList = [rootNode nodesForXPath:@"//foo:title"
                                  namespaces:dict
                                       error:&error];
NSLog(@"%@", titleList);   // titleリストが出てくれますように。
  • そしたら!そしたら!
2010-01-15 23:47:42.284 samplePrj[43800:20b] 「著作権法改正」でもWinnyは相変わらず、逮捕続きのShareは減少 〜 ネットエージェント調べ:Enterprise:RBB TODAY (ブロードバンド情報サイト) 2010/01/15
2010-01-15 23:47:42.284 samplePrj[43800:20b] 犬も歩けば猫も歩く。: 松本人志が出演。「のだめカンタービレ」
2010-01-15 23:47:42.313 samplePrj[43800:20b] YouTube - 豊田エリー ♪ ぱなしのはなし
  • うひょー!!!!!やったぜ!タイトルが取得できた!!!!!

ということで嬉しくなったので今日はここまでにしました。あとはparseFeed的なメソッドか何かを作ろうと思います。