2012-04-09 3 views
1

現在のiPhoneアプリプロジェクトのXML要素をどのようにループさせるのか非常に混乱しています。私は自分のコードを表示し、私の質問を明確にします。xcode 4.2 XMLデータ要素をループする

ここで私が使用しているサンプルXMLれる:私のテーブルのデータを取得

<restaurant_details> 
    <total_results>90</total_results> 
    <restaurant> 
     <name>Through the Garden</name> 
     <distance_from_current_location>0.55</distance_from_current_location> 
     <restaurant_id>123</restaurant_id> 
     <longitude>-84.373734</longitude> 
     <latitude>39.258606</latitude> 
     <address>10738 Kenwood Rd | cincinnati ,OH | 45242</address> 
     <phone_number>513-791-2199</phone_number> 
     <restaurant_type>General</restaurant_type> 
    </restaurant> 
</restaurant_details> 

を:

- (void)get_table_data { 
    NSString *day = [self dateInFormat:@"%A"]; 

    NSLog (@"At get_table_data"); 

    NSURLRequest *theRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.url.com"] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0]; 
    NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self]; 

    if (theConnection) { 
     NSLog (@"At connection"); 
     receivedData = [NSMutableData data]; 
    } 
} 

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { 
    [receivedData setLength:0]; 
} 

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { 
    [receivedData appendData:data]; 
} 

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { 

} 

-(void)connectionDidFinishLoading:(NSURLConnection *)connection { 
    //  NSString *theXML = [[NSString alloc] initWithBytes: [myWebData mutableBytes] length:[myWebData length] encoding:NSUTF8StringEncoding]; 
    //  NSLog(@"%@",theXML);[theXML release]; 
    if(parser){ 
     parser = nil; 
    } 

    parser = [[NSXMLParser alloc] initWithData: receivedData]; 
    [parser setDelegate: self]; 
    [parser setShouldResolveExternalEntities: YES]; 
    [parser parse]; 
} 

そして、私のパーサコード:

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict{ 
    NSLog (@"At parser"); 
    currentElement = elementName; 

    if ([currentElement isEqualToString:@"restaurant_details"]) { 
     if ([currentElement isEqualToString:@"total_results"]) { 
      //NSLog(@"Element: %@", currentElement); 
     }else if ([currentElement isEqualToString:@"restaurant"]) { 
      restaurantObj = [[DOR_RestaurantClass alloc]init]; 
     } 
    } 
} 

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{ 
    if([currentElement isEqualToString:@"name"]) { 
     restaurantObj.name=[NSString stringWithFormat:@"%@",string]; 
     //NSLog(@"Name to be saved in Array :- %@",string); 
    } 
    if([currentElement isEqualToString:@"distance_from_current_location"]) { 
     restaurantObj.distance=[NSString stringWithFormat:@"%@",string]; 
     //NSLog(@"Name to be saved in Array :- %@",string); 
    } 
    if([currentElement isEqualToString:@"restaurant_id"]) { 
     restaurantObj.restId=[NSString stringWithFormat:@"%@",string]; 
     //NSLog(@"Name to be saved in Array :- %@",string); 
    } 
    if([currentElement isEqualToString:@"address"]) { 
     NSArray *stringArray = [string componentsSeparatedByString:@" | "]; 
     restaurantObj.address=[stringArray objectAtIndex:0]; 
     restaurantObj.address2=[stringArray objectAtIndex:1]; 
     restaurantObj.address3=[stringArray objectAtIndex:2]; 
     //NSLog(@"Name to be saved in Array :- %@",string); 
    } 
    if([currentElement isEqualToString:@"phone_number"]) { 
     restaurantObj.phone=[NSString stringWithFormat:@"%@",string]; 
     //NSLog(@"Name to be saved in Array :- %@",string); 
    } 
    if([currentElement isEqualToString:@"description"]) { 
     restaurantObj.description=[NSString stringWithFormat:@"%@",string]; 
     //NSLog(@"Name to be saved in Array :- %@",string); 
    } 
    if([currentElement isEqualToString:@"image_url"]) { 
     restaurantObj.image=[NSString stringWithFormat:@"%@",string]; 
     //NSLog(@"Name to be saved in Array :- %@",string); 
    } 
    if([currentElement isEqualToString:@"restaurant_type"]) { 
     //restaurantObj.Name=[NSString stringWithFormat:@"%@",string]; 
     //NSLog(@"Name to be saved in Array :- %@",string); 
    } 
    NSLog (@"At parser2"); 
    if(!currentElementValue) 
     currentElementValue=[[NSMutableString alloc] initWithString:string]; 
    else 
     [currentElementValue appendString:string]; 
    NSLog(@"the parser just found this text in a tag:%@",string); 
} 

-(void)parser:(NSXMLParser*)parser didEndElement:(NSString*)elementName namespaceURI:(NSString*)namespaceURI qualifiedName:(NSString*)qualifiedName { 
    NSLog(@"Current element in End Element Category:- %@",currentElement); 
    if([elementName isEqualToString:@"restaurant"]) { 
     [listItems addObject:restaurantObj]; 
     NSLog(@"Array: %@", listItems); 
    }else{ 
     currentElementValue=nil; 
    } 

} 

は、ここに私のための私の.hですレストランクラス:

#import <Foundation/Foundation.h> 

@interface DOR_RestaurantClass : NSObject 

@property (nonatomic, retain) NSString *restId; 
@property (nonatomic, retain) NSString *image; 
@property (nonatomic, retain) NSString *name; 
@property (nonatomic, retain) NSString *description; 
@property (nonatomic, retain) NSString *distance; 
@property (nonatomic, retain) NSString *address; 
@property (nonatomic, retain) NSString *address2; 
@property (nonatomic, retain) NSString *address3; 
@property (nonatomic, retain) NSString *phone; 
@property (nonatomic, retain) NSString *expires; 

@end 

そして、私の.m:

#import "DOR_RestaurantClass.h" 

@implementation DOR_RestaurantClass 
@synthesize restId; 
@synthesize image; 
@synthesize name; 
@synthesize description; 
@synthesize distance; 
@synthesize address; 
@synthesize address2; 
@synthesize address3; 
@synthesize phone; 
@synthesize expires; 

@end 

私は自分のデータを取得していますなど、そのためには、問題ではないのです。私の質問はこれです:私のXMLデータに複数の "レストラン"タグがある場合、レストランデータをまとめて保存するためにXMLをどのように並べ替えますか?私はPHPから来ているので、レストランのタグについてforeachを行っていましたが、NSXMLParserがどのようにデータを分離しておくことになっているのかよくわかりません。私はこの情報を最後にNSMutableArrayに入れます。私はどこから始めるべきか分かりませんし、これを行う上での良い例は見つけられません。すべての助けが大歓迎です。

は、これは私がNSLogにそれを印刷するとき

マイ配列listItems(NSMutableArrayのは)nullで更新されています。

+0

+1、助けてください。 :) – mAc

答えて

2

まず、.hと.mファイルのみを持つObj cクラスを作成します。そして、今そのなどなど..名、距離、経度、緯度のような特性を有するいくつかのNSStringの変数を作成

のコード部分: -

didStartElement

でレストランタグ内のオブジェクトを作成します私はちょうど(オブジェクトを初期化)を作成するために、Uを告げ、そのクラス: - :

-

currentElement = elementName; 

    if([currentElement isEqualToString:@"restaurant"]) { 
     classObj = [[MyRestaurentClass alloc]init]; 
    } 

今foundCharactersでは、このような他のタグを見つけます

今didEneElement最後の部分: -

パーサクラスでMutubaleArrayを作成し、didEndElementでその配列にclassObjを追加します -

if([elementName isEqualToString:@"restaurent"]) { 
     NSLog(@"Current element in End Element Category:- %@",currentElement); 
     [ObjectsMutableArray addObject:classObj]; 

    } 

そして、それがすべてです。 Uは、あなたがこのように記述する必要がいけない

まず

UPDATE ...構文解析を終えrの場合はループすなわち: -

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict{ 
    NSLog (@"At parser"); 
    currentElement = elementName; 

    if ([currentElement isEqualToString:@"restaurant_details"]) { 
     if ([currentElement isEqualToString:@"total_results"]) { 
      //NSLog(@"Element: %@", currentElement); 
     }else if ([currentElement isEqualToString:@"restaurant"]) { 
      restaurantObj = [[DOR_RestaurantClass alloc]init]; 
     } 
    } 
} 

何私はdidStartElementのための答えに書いたことはdidStartElementがそれぞれn個すべてのタグのために呼ばれているとして十分なものです。

を参照してください。あなたのXMLに準拠するNSStringを持つクラスを作成してください。そのクラスのObjectを作成し、それをdidStartElementで初期化するだけです。 foundCharacters If条件ループに従って、必要なデータをclassObject変数に追加します。 XMlParserが</restaurent>タグに入ったときは、didEndElementメソッドに入ります。そこにdidEndElementのようにそのクラスオブジェクト(オブジェクト)を配置するだけです。

あなたNSMutableArrayのについては[OK]を、あなたはこのようdidStartDocumentで配列を初期化している: -

  • (無効)parserDidStartDocument:(NSXMLParser *)パーサ{ のlistItems = [[NSMutableArrayののalloc]のinit]; }

私は上記のコードを変更しましたので、回答全体を注意深くお読みください。 まだ疑問が残っている場合は...

+0

こんにちは、あなたのポストに感謝します。しかし、 'classObj'データがどのように配列に設定されているのか説明できますか?インデックスやキー名でデータを呼び出すかどうかはわかりません。 – James

+0

また、[listItems addObject:restaurantObj]; NSLog(@ "Array:%@"、listItems); '上記の新しいコードを投稿します。 – James

+0

何らかの理由で、更新された応答が届かない私はこれを試し、あなたに知らせるでしょう。私はしばらくの間、回避策を講じていましたが、正しい方法でやります。 – James