如何使用NSXMLParser解析多个XML标记

时间:2010-11-07 18:38:51

标签: iphone objective-c ios nsxmlparser

我正在解析XML文件并填充表格视图。 XML的格式如下:

<article>
  <title>Title 1</title>
  <last-modified>MM/DD/YYY</last-modified>
</article>
...

我目前正在使用NSMutableString来收集所有文章标题并在- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string方法中附加字符串。然后在适当的时候,我将articleTitle添加到包含所有文章标题的NSMutableArray,并按照您的预期从数组中填充表格。

但是,现在我想切换到使用带有副标题的表格视图单元格(我想将最后修改日期作为detailTextLabel,标题作为textLabel)。通过解析分为几种方法(即2 parser方法和foundCharacters方法)的方式,我不确定如何“收集”数据并填写表格从那些数据。

最好的方法是什么?我可以以某种方式填充NSDictionary或其他东西,并在构建表格单元格时按键检索项目吗?

我似乎无法找到解决这个问题的最佳方法。

提前致谢!

3 个答案:

答案 0 :(得分:5)

如果您愿意,可以使用DOM解析器,它可能会让您的生活更轻松,但如果由于某种原因您想坚持使用NSXMLParser,请继续阅读。

你希望你给解析器的对象作为你的委托(实现NSXMLParserDelegate的东西)基本上在数据交付时累积数据。

重要细节已被忽视:对于各种标签的“内容”,您实际上可以接听多次parser:foundCharacters:的来电。绝对没有要求解析器立刻将它全部交给您。如果它想要,它可以一次向你发送一个字符,你必须妥善处理它。

以下假设以下ivars:

NSMutableArray articles_;
NSMutableString currentCharacters_;
Article currentArticle_; // Article has title and lastModified properties.

以下是委托如何实现一些相关消息的示例(以下代码显然没有错误处理):

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
    if ([elementName isEqualToString:@"article"]) {
        NSAssert(currentArticle_ == nil, @"Uh oh! Bad XML!");
        currentArticle_ = [[Article alloc] init];
        return;
    }
    if ([elementName isEqualToString:@"title"]) {
        NSAssert(currentCharacters_ == nil, @"Uh oh! Bad XML!");
        currentCharacters_ = [[NSMutableString alloc] init];
        return;
    }
    if ([elementName isEqualToString:@"last-modified"]) {
        NSAssert(currentCharacters_ == nil, @"Uh oh! Bad XML!");
        currentCharacters_ = [[NSMutableString alloc] init];
        return;
    }
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    if ([elementName isEqualToString:@"article"]) {
        [articles_ addObject:currentArticle_];
        [currentArticle_ release], currentArticle_ = nil;
        return;
    }
    if ([elementName isEqualToString:@"title"]) {
        currentArticle_.title = currentCharacters_;
        [currentCharacters_ release], currentCharacters_ = nil;
        return;
    }
    if ([elementName isEqualToString:@"last-modified"]) {
        [currentArticle_ setLastModifiedWithString:currentCharacters_];
        [currentCharacters_ release], currentCharacters_ = nil;
        return;
    }
}

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

答案 1 :(得分:0)

您可以阅读官方Event-Driven XML Programming Guidetutorial

我也可以建议尝试touchXML而不是NSXMLParser

答案 2 :(得分:0)

我使用DOM Parser,如果你没有解析很多数据,它更干净,更容易..推荐谷歌的GDATA

这里有一个StackOverflow Questio n

NSError *error;
GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:xmlData options:0 error:&error];
if (doc == nil) { return nil; }

// get number of hits
GDataXMLElement * article = [[doc nodesForXPath:@"//article" error:nil] objectAtIndex:0];

// title
NSLog([[[entry elementsForName:@"title"] objectAtIndex:0] stringValue]], nil);

// last-modified
NSLog([[[entry elementsForName:@"last-modified"] objectAtIndex:0] stringValue]], nil);