使用NSXMLParser仅解析前十个帖子,然后分别解析下一个帖子

时间:2012-07-03 19:01:09

标签: ios xcode rss nsxmlparser nsxml

我正在使用NSXmlParser来解析rss feed。到目前为止一切运作良好。

我预计rss feed最终将包含数十个/数百个帖子。我目前的解决方案是读取整个RSS Feed并显示结果。但是我想只阅读前十个帖子(以防止它解析可能有数百个项目)。然后在稍后的时间(例如当用户到达表的末尾时)来解析接下来的十个帖子。

所以我的问题是如何解析前十个帖子,然后解析接下来的十个帖子,接下来的十个帖子等等......

以下是我用来获取所有帖子的内容:

- (void)parseXMLFileAtURL:(NSString *)URL
{   
    myArray = [[NSMutableArray alloc] init];

    //convert the path to a proper NSURL or it won't work
    NSURL *xmlURL = [NSURL URLWithString:URL];

    rssParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL];
    [rssParser setDelegate:self];
    [rssParser parse];

}

- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
    //error
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{            

    currentElement = [elementName copy];

    if ([elementName isEqualToString:@"item"]) {
        //clear out our story item caches...
        item = [[NSMutableDictionary alloc] init];

    }

}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{     

    if ([elementName isEqualToString:@"item"]) {
        // save values to an item, then store that item into the array...
    }

}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{

    // save the characters for the current item...

}

- (void)parserDidEndDocument:(NSXMLParser *)parser {

    [myTable reloadData];

}

4 个答案:

答案 0 :(得分:7)

在与其他人不同的风格回答中,我想做出贡献,如果你的解析器花了很长时间来解析10到100之间的差异是一个重要的人类可测量的数量,那么你做错了。最好是:

  1. 分析您的解析代码以找到减速(或找到更高性能的XML库)
  2. 在背景线程上解析整个批次
  3. 仅向用户显示前10个
  4. 在内存中显示其余部分。
  5. 这是一个双赢,因为一次解析它可以使代码更简单,更少的错误,并且一次“加载”(显示)一个rss“页面”将是闪电般快速的,你的用户会爱你(见Instagram上关于伪造速度的例子)

答案 1 :(得分:0)

您可以调用[rssParser abortParsing]来停止解析。停止后,需要手动剪切xml的第一部分。或以某种方式告诉网络服务。 NSXMLParser不会为您提供跳转的权限。

答案 2 :(得分:0)

绝对在你的班级标题中制作一个计数变量:

...
@private
  NSUInteger rssCounter;
...
@property (nonatomic, assign) NSUInteger rssCounter;
...

在你的委托中使用init方法:

rssCounter = 0;

然后只要在元素结尾处增加此变量,然后如@Metalmi所述,在启动元素时使用if else块中的中止解析。

之后,创建一个方法,当需要再加载10个变量时,将该变量重置为0,当需要再次触发整个过程时,可以调用该方法。

类似的东西:

- (void)restartParsing:(NSString *)url
{
  rssCounter = 0
  [self parseXMLFileAtURL:url];
}

希望这有帮助。

答案 3 :(得分:0)

我同意@coneybeare,它似乎是在后台线程中解析xml并将结果存储在内存中的正确方法。

尽管如此,如果您仍想“逐页”解析xml,可以使用libxml中的xmlParseChunk来完成此操作(例如,请参阅XMLPerformance sample)。您需要手动计算项目并将剩余部分存储在某处,但我想这是您可以开箱即用的最接近的功能。

另一种方法是使用任何Objective-C免费的开源xml解析器(甚至可能是DOM解析器,例如TBXML)并以适合您的方式分解其内部解析循环。