从XML源过滤UITableView

我有我在UITableView中显示的这个XML:

<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> 

我正在使用这段代码来保存它:

 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个参数来sorting我的TableView:

  1. <trip duration="03:50">时间

  2. <price>

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

按时间和价格sorting数据的最好方法是什么? 任何想法,我应该如何重新格式化的代码?

PS我正在使用SegmentedControl重新加载TableView并相应地进行sorting。

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

例如,我的parsing器如下所示:

 @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 ,它看起来像:

 - (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 ,但这应该让你知道它是如何工作的。

你需要把这些全部放到一个数组中,然后在sorting后使用数组加载UITableView。