2012-04-09 54 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中。我只是不知道從哪裏開始,並且找不到這樣做的好例子。任何和所有的幫助,不勝感激。

這已更新

我的陣列listItems(NSMutableArray的)是null當我把它打印到NSLog

+0

+1,希望它有幫助。 :) – mAc 2012-04-12 04:40:34

回答

2

首先創建一個只有.h和.m文件的對象類。並且在創建具有類似於名稱,距離,經度,緯度..等等等等,性能有一定的NSString變量

現在,代碼部分: -

在didStartElement

在餐廳標籤創建的對象那類,我只是告訴u到創建(初始化對象): -

currentElement = elementName; 

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

現在foundCharacters找到其他標籤是這樣的: -

if([currentElement isEqualToString:@"name"]) { 
     classObj.Name=[NSString stringWithFormat:@"%@",string]; 
     NSLog(@"Name to be saved in Array :- %@",string); 
    } 
    if ([currentElement isEqualToString:@"longitude"]) 
    { 
     classObj.longitude =[NSString stringWithFormat:@"%@",string];    
    } 
} 

現在最後一部分在didEneElement: -

創建分析器類一MutubaleArray並添加classObj在didEndElement數組中: -

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

    } 

而這一切。 üR 3與解析完..

UPDATE

首先你不必這樣寫的。如果循環即: -

- (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的類。只需創建該類的對象並在didStartElement中初始化它。 在foundCharacters中,您將根據If Conditions循環在ClassObject變量中添加Required數據。每當XMlParser進入</restaurent>標籤時,它將進入didEndElement方法,並且您只需將該類對象(對象)放入該數組中,就像我在didEndElement中一樣。

好關於你的NSMutableArray,你有沒有初始化數組中didStartDocument這樣的: -

  • (無效)parserDidStartDocument:(的NSXMLParser *)解析器{ 時listItems = [[NSMutableArray裏的alloc]初始化]。 }

我已更改上面的代碼,所以請仔細閱讀整個答案。 如果你還有什麼懷疑發短信給我...

+0

你好,感謝您的留言。但是,你能解釋一下'classObj'數據是如何設置到數組中的?我不確定我是否會按索引或鍵名稱調用數據。 – James 2012-04-13 14:14:59

+0

還有一個問題,當我使用'[listItems addObject:restaurantObj]; NSLog(@「Array:%@」,listItems)時,它顯示數組爲null;'我會在上面發佈我的新代碼。 – James 2012-04-13 15:25:07

+0

由於某種原因,它從來沒有通知我您的更新回覆。我會試試這個,讓你知道。我暫時做了一個解決方法,但寧願以正確的方式做。 – James 2012-05-21 19:33:55