NSXMLParser 将 RSS 解析为自定义对象

Posted

技术标签:

【中文标题】NSXMLParser 将 RSS 解析为自定义对象【英文标题】:NSXMLParser Parsing RSS into a Custom Object 【发布时间】:2011-06-13 13:11:46 【问题描述】:

我的 nsxmlparser 可以很好地解析新闻提要:

http://www.skysports.com/rss/0,20514,12433,00.xml

然而,在将它保存到我的自定义对象中时,虽然我收到了 xml 中每个条目的输出,但它只存储了一条恰好是最后一条的记录。

请看我的代码:

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

    if ([elementName isEqualToString:@"rss"]) 
        currentNews = [[NewsParse alloc] init];
    


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




    if ([elementName isEqualToString:@"description"]) 
        currentNews.newsTitle = currentNodeContent;
        NSLog(@"description = %@",currentNodeContent);
    



    if([elementName isEqualToString:@"rss"])
    
        [news addObject:currentNews];
        [currentNews release];
        currentNews = nil;
        [currentNodeContent release];
        currentNodeContent = nil;
    


此方法适用于 twitter 提要,但现在我假设因为 xml 的格式不同,我无法让它工作。

我对使用 NSXMLParser 还是很陌生,所以任何帮助都会很酷:)

【问题讨论】:

您有什么理由错过[NewsParse alloc] 中的init 哎呀,我错过了。无心工作 那是因为你的init 可能是空的。不过,您应该在问题中更正它,以免误导回答者。 【参考方案1】:

查看 RSS 提要,您似乎正在寻找错误的标签来开始和结束您的对象。你需要更换

[elementName isEqualToString:@"rss"]

[elementName isEqualToString:@"item"]

在这两个地方。 您现在的做法是将整个页面视为 1 个对象。您需要将每个“项目”(<item> </item>)视为一个对象。您成功获取要保存的最后一个对象的原因是因为您每次运行项目时都会替换每个“描述”。在您实际保存之前,它会一遍又一遍地替换字符串。最后一个对象在保存之前永远不会被替换,因此您看到的唯一对象已保存..

【讨论】:

【参考方案2】:

嗯,currentNews.newsTitle 每次都会改变,一旦它读取到关闭的 rss 标签,它就具有最后一个提要的值。你的 currentNews 是什么类型的对象?如果要保留所有不同的标题,则必须将它们添加到某种包含多个值的对象中,例如数组,当您找到描述的结束标记时,只需将 currentNodeContent 的字符串复制到单个新闻实例中即可。

我实际上会在任何比较之外的 didEndElement 标记中分配 currentNews 的实例,以防万一您要查找更多元素。结束标签可能是这样的:

-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName 
    if ([elementName isEqualToString:@"title"]) 
        self.currentNews.newsTitle = [[NSString alloc] initWithString:currentNodeContent];
    
    if ([elementName isEqualToString:@"description"]) 
        self.currentNews.newsDescription = [[NSString alloc] initWithString:currentNodeContent];
    
    if ([elementName isEqqualToString:@"link"]) 
        self.currentNews.newsLink = [[NSString alloc] initWithString:currentNodeContent];
    
    if ([elementName isEqualToString:@"guid"]) 
        self.currentNews.newsGuid = [[NSString alloc] initWithString:currentNodeContent];
    
    if ([elementName isEqualToString:@"pubDate"]) 
        self.currentNews.newsPubDate = "probably a date formatter here";
    
    if ([elementName isEqualToString:@"cathegory"]) 
        self.currentNews.newsCathegory = [[NSString alloc] initWithString:currentNodeContent];
    
    blah...
    blah...
    if ([elementName isEqualToString:@"item"]) 

        [news addObject:currentNews];

        [self.currentNews.newsTitle release];
        [self.currentNews.newsDescription release];
        [self.currentNews.newsLink release];
        [self.currentNews.newsGuid release];
        blah...
        blah...
        blah...
    

并在您的 init 方法中分配您的 currentNews 对象(从您的 didStartElement 中删除它)并在您的 dealloc 方法中释放它。哦,@Louie 是对的,您需要将您的新闻视为一个数组对象,其中显然有几个 currentNews,这个 currentNews 或 item 是您的解析器应该关注的。在解析“仅一项”中的所有元素后,当它读取该“一项”的最后一个元素标记时,将其添加到新闻数组中,因为之后您的解析器将简单地循环并查找下一项。

【讨论】:

以上是关于NSXMLParser 将 RSS 解析为自定义对象的主要内容,如果未能解决你的问题,请参考以下文章

NSXMLParser读取XML文件并将数据显示到TableView上

快速将数据解析为自定义数据对象

尝试将变量保存为自定义解析对象列表(UserRecipe)并将它们打印到 xcode 控制台

Azure APIM:将 JSON 响应转换为自定义 XML 格式

iOS - OC - XML 解析 - NSXMLParser

Swift之深入解析如何将代码添加为自定义LLDB命令