iphone - 将具有大量子节点的 XML 解析为 UITableView

标签 iphone objective-c ios xml cocoa-touch

我有一个如下所示的 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>

我想获取所有参数并将它们放入 3 个 UITableViewCell 中。如您所见,有 3 个航类及其相关数据。 我一直在尝试在 TableView 中解析它,但我只得到了 <price>事情进展。 您将如何处理解析 XML 文件中结构复杂的参数?我的意思是我怎样才能得到takeoff date参数等等? 据我所知,您无法应用我正在使用的策略,如下所示:

- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
        if ([elementname isEqualToString:@"price"]) 
        {
            currentTweet.dateCreated = currentNodeContent;
        }

任何帮助将不胜感激。提前致谢。

最佳答案

这是我经常用来从 XML 文件构建字典的代码,该字典遵循一些定义明确的重复元素(在本例中为 "trip")的基本模型,以及一系列其中的一些数据元素,其中一些我正在读取标签的属性(在本例中为 "takeoff""landing""flight "),而其他人则读取开始标签和结束标签之间的数据(在本例中,只是 "price")。

我有以下 ivars:

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

然后代码如下:

- (void)viewDidLoad
{
    [super viewDidLoad];

    trips = [[NSMutableArray alloc] init];

    // I'm getting my xml from my bundle. You get it however you're currently getting it.

    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(@"%s trips=%@", __FUNCTION__, trips);

    // generally I immediately kick off the reload of the table, but maybe 
    // you want to grok the trips dictionary first.
    //        
    // [self.tableView reloadData];
}

正如你所猜到的,我试图最终得到我们已经习惯于解析 JSON 文件的那种嵌套数组/字典结构。显然,我不喜欢这样的事实:我必须在代码中预先识别 XML 文件的某些结构(外部数组具有 "trip" 标记,即 “takeoff”“landing”“flight”有属性,但“price”没有)等。但这有点比我第一次尝试 XML 解析(到处都是硬编码值)要好。叹息。

关于iphone - 将具有大量子节点的 XML 解析为 UITableView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13545811/

相关文章:

iphone - 如何初始化UIGestureRecognizer?

objective-c - 在 iOS5 中实现库时获取 "apple mach-o linker id error undefined symbols for architecture i386"

ios - Objc 获取类的所有属性失败

ios - 删除委托(delegate)方法的 2 个实现中的重复代码

iphone - UITableView 显示键值对

ios - 手势: Failed to receive system gesture state notification before next touch

ios - 使用 Swift 创建 iOS 应用程序,需要知道如何使用 mysql 数据库跟踪用户数据?

objective-c - 当您未声明变量时,编译器/运行时是否会默默地为您声明变量?

ios - 单独在 Swift 中创建自定义 sqlite 函数

ios - UIBezierPath 和 CAShapeLayer