从XML源过滤UITableView [英] Filtering UITableView from XML source

查看:33
本文介绍了从XML源过滤UITableView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有在UITableView中显示的XML:

I have this XML which I display in UITableView:

<result>
<trip duration="03:30">
<takeoff date="2010-06-19" time="18:40" city="Moscow"/>
<landing date="2010-06-19" time="20:10" city="Novgorod"/>
<flight carrier="Rossiya" number="8395" eq="320"/>
<price>13429.00</price>
</trip>
<trip duration="03:40">
<takeoff date="2010-06-19" time="09:20" city="Omsk"/>
<landing date="2010-06-19" time="11:15" city="Paris"/>
<flight carrier="AirFrance" number="1145" eq="320"/>
<price>13229.00</price>
</trip>
<trip duration="03:50">
<takeoff date="2010-06-19" time="07:20" city="Omsk"/>
<landing date="2010-06-19" time="14:15" city="Barcelona"/>
<flight carrier="AirFrance" number="1100" eq="320"/>
<price>13329.00</price>
</trip>
</result>

我正在使用以下代码进行保存:

I'm using this code to save it:

if ([elementname isEqualToString:@"trip"]) {
    currentTweet = [Tweet alloc];
    isStatus = YES;
    flightTime = [attributeDict objectForKey:@"duration"];
    currentTweet.flightDuration = [NSString stringWithFormat:@"Flight duration is: %@", flightTime];
}

if([elementname isEqualToString:@"takeoff"]) {

    takeoffPlace = [attributeDict objectForKey:@"city"];
} 
if ([elementname isEqualToString:@"landing"]) {
    landingPlace = [attributeDict objectForKey:@"city"];
    currentTweet.content = [NSString stringWithFormat:@"%@ - %@", takeoffPlace, landingPlace];
}

if ([elementname isEqualToString:@"takeoff"]) {
    takeoffDate = [attributeDict objectForKey:@"date"];
    takeoffTime = [attributeDict objectForKey:@"time"];
    currentTweet.takeOffAll = [NSString stringWithFormat:@"Take off date %@. Take off time %@", takeoffDate, takeoffTime];
}

if ([elementname isEqualToString:@"landing"]) {
    landingDate = [attributeDict objectForKey:@"date"];
    landingTime = [attributeDict objectForKey:@"time"];
    currentTweet.landingAll = [NSString stringWithFormat:@"Landing date %@. Landing time %@", landingDate, landingTime];
}

if ([elementname isEqualToString:@"flight"]) {
    companyName = [attributeDict objectForKey:@"carrier"];
    companyNumber = [attributeDict objectForKey:@"number"];
    eqStuff = [attributeDict objectForKey:@"eq"];
    currentTweet.companyInfo = [NSString stringWithFormat:@"Carrier: %@ Flight number: %@ Eq: %@", companyName, companyNumber, eqStuff];
}

我需要按2个参数对TableView进行排序:

I need to sort my TableView by 2 parameters:


  1. <行程持续时间= 03:50> 时间

< price>

我不确定我是否使用正确的结构-基本上所有数据都是分配给单独数据类的NSString,然后将其分配给UITableView单元内的UILabels。

I'm not sure whether I'm using the right structure - basically all the data is NSStrings assigned to a separate data class which are then assigned to UILabels inside UITableView cell.

按时间和价格对数据进行排序的最佳方法是什么?关于如何重新格式化代码的任何想法?

What would be the best way to sort the data by time and price? Any ideas on how I should reformat the code?

P.S。我正在使用SegmentedControl重新加载TableView并对其进行相应的排序。

P.S. I'm using SegmentedControl to reload the TableView and sort it accordingly.

推荐答案

您可以将结果存储在字典条目数组中,然后您可以使用 sortedArrayUsingComparator 对数组进行排序,就像我在此答案结尾处演示的那样。

You can store your results in an array of dictionary entries, which you can then sort the array using sortedArrayUsingComparator like I demonstrate at the end of this answer.

例如,我的解析器如下:

For example, my parser was as follows:

@interface XmlParserViewController () <NSXMLParserDelegate>
{
    NSMutableArray *trips;
    NSMutableDictionary *currentTrip;
    NSMutableString *currentElement;
}
@end

@implementation XmlParserViewController


- (void)viewDidLoad
{
    [super viewDidLoad];

    trips = [[NSMutableArray alloc] init];

    // clearly I'm reading your XML from a file in my bundle, but you'll get it
    // how ever you're retrieving it from your remote source

    NSString *filename = [[NSBundle mainBundle] pathForResource:@"results" ofType:@"xml"];
    NSData *data = [NSData dataWithContentsOfFile:filename];
    NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
    parser.delegate = self;
    [parser parse];
}

#pragma mark - NSXMLParserDelegate methods

#define kRowElementTag @"trip"

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{
    NSArray *attributeElementNames = @[@"takeoff", @"landing", @"flight"];
    NSArray *foundCharacterElementNames = @[@"price"];

    if ([elementName isEqualToString:kRowElementTag])
    {
        currentTrip = [[NSMutableDictionary alloc] init];
        [trips addObject:currentTrip];
        if (attributeDict)
            [currentTrip setObject:attributeDict forKey:elementName];
    }
    else if (currentTrip)
    {
        if ([attributeElementNames containsObject:elementName])
        {
            if (attributeDict)
                [currentTrip setObject:attributeDict forKey:elementName];
        }
        else if ([foundCharacterElementNames containsObject:elementName] && currentElement == nil)
        {
            // you can change this to just grab a few fields ... add whatever fields you want to this

            currentElement = [[NSMutableString alloc] init];
            [currentTrip setObject:currentElement forKey:elementName];
        }
    }
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    if ([elementName isEqualToString:kRowElementTag])
    {
        currentTrip = nil;
    }
    else if (currentElement)
    {
        currentElement = nil;
    }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    if (currentElement)
    {
        [currentElement appendString:string];
    }
}

- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError
{
    NSLog(@"%s error=%@", __FUNCTION__, parseError);

    // we should handle the error here
}

- (void)parserDidEndDocument:(NSXMLParser *)parser
{
    NSLog(@"Order in XML:");

    for (NSDictionary *trip in trips)
    {
        NSLog(@"    %@ %@ %@ %@ %@ %@", trip[@"flight"][@"carrier"], trip[@"flight"][@"eq"], trip[@"takeoff"][@"date"], trip[@"takeoff"][@"time"], trip[@"trip"][@"duration"], trip[@"price"]);
    }

    NSArray *sortedTrips = [self sortResultsByDurationAndPrice];

    NSLog(@"Sorted order:");

    for (NSDictionary *trip in sortedTrips)
    {
        NSLog(@"    %@ %@ %@ %@ %@ %@", trip[@"flight"][@"carrier"], trip[@"flight"][@"eq"], trip[@"takeoff"][@"date"], trip[@"takeoff"][@"time"], trip[@"trip"][@"duration"], trip[@"price"]);
    }

    // you can now update your user interface or do whatever at this point
    //
    // [self.tableView reloadData];
}

您会注意到, parserDidEndDocument 调用 sortResultsByDurationAndPrice 如下:

You'll notice that that parserDidEndDocument calls sortResultsByDurationAndPrice which looks like:

- (NSArray *)sortResultsByDurationAndPrice
{
    NSArray *sortedTrips = [trips sortedArrayUsingComparator: ^(id trip1, id trip2) {

        double duration1 = [self durationFromString:trip1[@"trip"][@"duration"]];
        double duration2 = [self durationFromString:trip2[@"trip"][@"duration"]];

        double price1 = [trip1[@"price"] doubleValue];
        double price2 = [trip2[@"price"] doubleValue];

        if (duration1 < duration2 || (duration1 == duration2 && price1 < price2)) {
            return (NSComparisonResult)NSOrderedAscending;
        }

        if (duration1 > duration2 || (duration1 == duration2 && price1 > price2)) {
            return (NSComparisonResult)NSOrderedDescending;
        }

        return (NSComparisonResult)NSOrderedSame;
    }];

    return sortedTrips;
}

// this assumes that duration is in the form of "h:mm"

- (double)durationFromString:(NSString *)durationString
{
    NSArray *durationArray = [durationString componentsSeparatedByString:@":"];

    return [durationArray[0] doubleValue] + [durationArray[1] doubleValue] / 60.0;
}

// sort by date and time not used, but was part of my original answer
// so I provide it here for the sake of completeness

- (NSArray *)sortResultsByDateTime
{
    NSArray *sortedTrips = [trips sortedArrayUsingComparator: ^(id trip1, id trip2) {

        NSComparisonResult dateComparison = [trip1[@"takeoff"][@"date"] compare:trip2[@"takeoff"][@"date"]];
        NSComparisonResult timeComparison = [trip1[@"takeoff"][@"time"] compare:trip2[@"takeoff"][@"time"]];

        if (dateComparison == NSOrderedAscending || (dateComparison == NSOrderedSame && timeComparison == NSOrderedAscending)) {
            return (NSComparisonResult)NSOrderedAscending;
        }

        if (dateComparison == NSOrderedDescending || (dateComparison == NSOrderedSame && timeComparison == NSOrderedDescending)) {
            return (NSComparisonResult)NSOrderedDescending;
        }

        return (NSComparisonResult)NSOrderedSame;
    }];

    return sortedTrips;
}

很显然,您可以调整 sortResults 根据您的字典条目的个人排列,但这应该使您了解其工作方式。

Clearly, you can just tweak your sortResults based upon your personal array of dictionary entries, but this should give you an idea of how it could work.

这篇关于从XML源过滤UITableView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆