[英]Filtering UITableView from XML source
我有這個XML,我在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>
我正在使用此代碼來保存它:
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進行排序:
<trip duration="03:50">
時間
<price>
我不確定我是否使用了正確的結構 - 基本上所有數據都是NSStrings分配給一個單獨的數據類,然后分配給UITableView單元內的UILabels。
按時間和價格對數據進行排序的最佳方法是什么? 關於如何重新格式化代碼的任何想法?
PS我正在使用SegmentedControl重新加載TableView並相應地對其進行排序。
您需要將所有內容放入一個數組中,然后在對其進行排序后使用該數組加載UITableView。
您可以將結果存儲在一個字典條目數組中,然后您可以使用sortedArrayUsingComparator
對數組進行排序,就像我在本答案結尾處所示。
例如,我的解析器如下:
@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
,但這應該讓您了解它是如何工作的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.