我使用 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>
提前感谢您的帮助
最佳答案
您需要将 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
parse 方法需要处理标签并构建数据结构 -
-(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
是从您的 URL 返回的 NSData。您将使用
self.deliData=[[DeliData alloc]init:menuData];
整个类(class)都可以在这里找到 - https://gist.github.com/paulw11/da11ab3c7688c6deb1d7
关于ios - UITableView - 使用 Hpple 数据设置表格 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26497946/