2012-11-27 27 views
1

我有这样的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我的TableView排序参数:

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

  2. <price>

我不知道我是否使用了正确的结构 - 基本上所有的数据分配到一个独立的数据类,然后分配给UITableView的细胞内UILabels NSString的。

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

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

回答

1

您可以将结果存储在字典条目数组中,然后您可以使用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基于你的个人字典条目,但这应该让你知道它如何工作。

+0

感谢您的详细解释。我会尝试一下并报告。 –

+0

@SergiusGee我意识到我是按日期和时间排序的,而您希望按持续时间和价格排序,所以我相应地修改了我的答案。 – Rob

2

你需要把所有的数据放到一个数组中,然后在排序后使用数组加载UITableView。

+0

是的,我想过,但是你怎么把这么多参数放在一个数组中?我的意思是UITableViewCell包含5个字符串,你会如何区分它们? –

+0

将5个字符串放入一个对象,然后放入数组中。然后使用自定义比较器排序这些对象。 – Tony

+0

听起来不错。任何想法如何比较'03:20'和'03:25'的持续时间? –