ios - UITableView - 使用 Hpple 数据设置表格 View

标签 ios objective-c xml uitableview

我使用 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/

相关文章:

ios - 自定义 Google Cast 迷你 Controller

objective-c - 滑动 UIView 以部分覆盖另一个 UIView

objective-c - 带 NSToolbar 的全屏应用

java - AES256加密 objective-c 实现

ios - 推送后自定义 titleView 更改位置并在堆栈中弹出新屏幕

ios - Reactive Cocoa - try catch 并重播

ios - Objective-C 预处理器指令问题

xml - 通过 Xquery 将 XML 中的数据转换为文本

java - ImageView 在不应该在布局内缩放的情况

java - setAdapter() 上的 NullPointer 异常