我使用hpple从网络上的xml文件中获取一些数据。在我的xml文件中,我有一堆不同的部分,我从中获取数据(约20)。
下面是我用来获取数据的代码
- (void)getMenuItems:(NSString*)url{
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
//NSLog(@"response == %@", response);
[self getDeli:data];
}
- (void)getDeli:(NSData*)deliData {
TFHpple *Parser = [TFHpple hppleWithHTMLData:deliData];
// 3
NSString *XpathQueryString = self.deliString;
NSArray *Nodes = [Parser searchWithXPathQuery:XpathQueryString];
// 4
NSMutableArray *newNodes = [[NSMutableArray alloc] initWithCapacity:0];
for (TFHppleElement *element in Nodes) {
// 5
Items *item = [[Items alloc] init];
[newNodes addObject:item];
// 6
item.title = [[element firstChild] content];
item.title = [[[element firstChild] content]stringByReplacingOccurrencesOfString:@"\n" withString:@""];
// 7
item.url = [element objectForKey:@"href"];
}
// 8
_deli = newNodes;
[self.tableView reloadData];
}
代码一切正常,我得到的数据问题是并非所有部分都有数据,设置部分的标题和在CellForRowAtIndexPath中设置数据是一件麻烦的事情,因为我改变它依赖于什么是返回并与节数相同。
因此,我希望找出返回的部分数量,并将其设置为tableview中的部分数,然后将部分标题设置为xml文件部分标题中的标题等。
因此,如果节或单元格为空,我不只是将标题和行高设置为0.
我希望这是有道理的......
这是xml文件的大部分内容
<day name="monday">
<meal name="DINNER">
<counter name="Chefs Choice">
<dish>
<name>Vegetable Samosa with Yogurt Sauce</name>
</dish>
<dish>
<name>Tomato Red Pepper Chutney</name>
</dish>
<dish>
<name>Curried Rice & Lentils</name>
</dish>
</counter>
<counter name="Entrée">
<dish>
<name>London Broil</name>
</dish>
<dish>
<name>Oven Roast Rosemary Red Potatoes</name>
</dish>
<dish>
<name>Glazed Fresh Carrots</name>
</dish>
<dish>
<name>Salad Bar</name>
</dish>
<dish>
<name>Cheddar Cheese & Bacon Potato Salad</name>
</dish>
</counter>
<counter name="Grill">
<dish>
<name>Hamburger</name>
</dish>
<dish>
<name>Classic Cheeseburger on a Toasted Bun</name>
</dish>
<dish>
<name>Chicken Sandwich</name>
</dish>
<dish>
<name>French Fries</name>
</dish>
</counter>
<counter name="International">
<dish>
<name>Shell Pasta</name>
</dish>
<dish>
<name>Spaghetti Sauce with Tomato Bits</name>
</dish>
<dish>
<name>Alfredo Sauce</name>
</dish>
</counter>
<counter name="Pizza">
<dish>
<name>Cheese Pizza</name>
</dish>
<dish>
<name>Pepperoni Pizza</name>
</dish>
<dish>
<name>Antipasto Pizza Slice</name>
</dish>
</counter>
<counter name="Soup">
<dish>
<name>Tomato Soup Florentine</name>
</dish>
</counter>
<counter name="Vegetable">
<dish>
<name>Eggplant Parmesan Casserole</name>
</dish>
</counter>
</meal>
</day>
感谢您的帮助
答案 0 :(得分:2)
您需要将XML结构解析为适当的数据模型对象,以便您可以通过层次结构访问数据。
这是一个可以工作的数据模型类 -
#import <Foundation/Foundation.h>
typedef NS_ENUM(NSInteger, DeliDay) {
DeliDayMonday=0,
DeliDayTuesday=1,
DeliDayWednesday=2,
DeliDayThursday=3,
DeliDayFriday=4,
DeliDaySaturday=5,
DeliDaySunday=6,
DeliDayUnknown=-1
};
@interface DeliData : NSObject
@property (strong,nonatomic,readonly) NSArray *days;
@property (strong,nonatomic,readonly) NSArray *meals;
@property (strong,nonatomic,readonly) NSArray *counters;
-(id)init:(NSData *)menuData;
-(NSArray *) itemsForMeal:(NSString *)meal onDay:(DeliDay)day atCounter:(NSString *)counter ;
-(NSArray *) mealsForDay:(DeliDay)day;
-(NSArray *) countersForMeal:(NSString *)meal onDay:(DeliDay)day;
+(DeliDay)deliDayForString:(NSString *)dayString;
+(NSString *)stringForDeliDay:(DeliDay)day;
@end
解析方法需要处理标记并构建数据结构 -
-(void)parseXML:(NSData *)menuData {
TFHpple *Parser = [TFHpple hppleWithXMLData:menuData];
NSString *XpathQueryString = @"//day";
NSArray *Nodes = [Parser searchWithXPathQuery:XpathQueryString];
for (TFHppleElement *element in Nodes) {
NSString *dayString=element.attributes[@"name"];
DeliDay day=[DeliData deliDayForString:dayString];
if (day != DeliDayUnknown) {
NSMutableDictionary *dayDict=(NSMutableDictionary *)self.menuData[day];
NSArray *mealsArray=[element childrenWithTagName:@"meal"];
for (TFHppleElement *mealElement in mealsArray) {
NSString *mealName=mealElement.attributes[@"name"];
NSMutableDictionary *counterDict=(NSMutableDictionary *)dayDict[mealName];
if (counterDict == nil) {
counterDict=[NSMutableDictionary new];
dayDict[mealName]=counterDict;
}
NSArray *countersArray=[mealElement childrenWithTagName:@"counter"];
for (TFHppleElement *counterElement in countersArray) {
NSString *counterName=counterElement.attributes[@"name"];
NSMutableArray *itemsArray=(NSMutableArray *)counterDict[counterName];
if (itemsArray == nil) {
itemsArray=[NSMutableArray new];
counterDict[counterName]=itemsArray;
}
NSArray *dishArray=[counterElement childrenWithTagName:@"dish"];
for (TFHppleElement *dishElement in dishArray) {
Item *newItem=[Item new];
TFHppleElement *dishNameElement=[dishElement firstChildWithTagName:@"name"];
NSString *text=[[dishNameElement firstTextChild].content stringByReplacingOccurrencesOfString:@"\n" withString:@""];
newItem.title=text;
TFHppleElement *dishUrlElement=[dishElement firstChildWithTagName:@"url"];
text=[[dishUrlElement firstTextChild].content stringByReplacingOccurrencesOfString:@"\n" withString:@""];
newItem.url=text;
[itemsArray addObject:newItem];
}
}
}
}
else {
NSLog(@"Invalid day name %@",dayString);
}
}
}
init
方法是 -
-(id)init:(NSData *)menuData {
if (self=[super init]) {
[self populateMenuArray];
[self parseXML:menuData];
}
return self;
}
其中menuData
是从您的网址返回的NSData。您可以使用
self.deliData=[[DeliData alloc]init:menuData];
全班都在这里 - https://gist.github.com/paulw11/da11ab3c7688c6deb1d7
答案 1 :(得分:0)
使用此
-(id)init:(NSData *)menuData {
if (self=[super init]) {
[self populateMenuArray];
[self parseXML:menuData];
}
return self;
}