Ios NSXMLParser将两个元素添加到一个TableView单元格
我正在尝试使用Ios NSXMLParser将两个元素添加到一个TableView单元格,ios,objective-c,uitableview,rss,nsxmlparser,Ios,Objective C,Uitableview,Rss,Nsxmlparser,我正在尝试使用NSXMLParser填充一个UITableView,其中包含来自几个单独RSS提要的文章标题: for (NSString* feedString in [[NSUserDefaults standardUserDefaults] objectForKey:@"RSSFeeds"]) { NSURL *url = [NSURL URLWithString:feedString]; parser = [[NSXMLParser alloc] initWithCont
NSXMLParser
填充一个UITableView
,其中包含来自几个单独RSS提要的文章标题:
for (NSString* feedString in [[NSUserDefaults standardUserDefaults] objectForKey:@"RSSFeeds"])
{
NSURL *url = [NSURL URLWithString:feedString];
parser = [[NSXMLParser alloc] initWithContentsOfURL:url];
[parser setDelegate:self];
[parser setShouldResolveExternalEntities:NO];
[parser parse];
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
element = elementName;
if ([element isEqualToString:@"item"])
{
item = [[NSMutableDictionary alloc] init];
title = [[NSMutableString alloc] init];
link = [[NSMutableString alloc] init];
}
}
如果只有一个RSS源,这似乎很有效,但一旦有多个RSS源,第二个RSS源的第一个标题将附加到第一个RSS源的最后一个标题,并且它们在表视图中共享同一单元格
我认为这种方法是问题的核心,但我正在努力使其正常工作:
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if ([element isEqualToString:@"title"])
{
[title appendString:string];
}
else if ([element isEqualToString:@"link"])
{
[link appendString:string];
}
}
我很感激我可能忽略了一些明显的东西,但任何指点都会很感激
我的didEnd
代码:
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:@"item"])
{
[item setObject:title forKey:@"title"];
[item setObject:link forKey:@"link"];
[feeds addObject:[item copy]];
}
}
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
[self.tableView reloadData];
}
当使用
NSXMLParser
时,创建对象结构完全取决于您,因为NSXMLParser
是哑的(我不是说它没有功能,我是说它把所有智能的东西都留给了您)
NSXMLParser
只需逐行读取文件,并告诉您在当前解析的行中找到了什么(在-foundCharacters
方法中)。
它不会告诉您以前的行或即将到来的行
我将为您提供最基本的代码,这些代码将基于解析的XML结构创建对象层次结构
根据您当前的需求,您可以使这变得更容易或更具识别力
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
attributes:(NSDictionary *)attributeDict
{
//NSLog(@"started element %@", elementName);
if(resultString) {
if(eliminateWhiteSpace)
[[objects objectAtIndex:[objects count] - 1] setStringValue:[resultString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
else
[[objects objectAtIndex:[objects count] - 1] setStringValue:resultString];
resultString = nil;
}
XMLNode* currentObject = [[XMLNode alloc] init];
if(!objects) {
objects = [[NSMutableArray alloc] init];
}
[objects addObject:currentObject];
[currentObject setNodeName:elementName];
if([[attributeDict allKeys] count] > 0) {
currentObject.attributes = attributeDict;
}
}
这里有几个类变量和一个
XMLNode
类。您必须根据自己的需要定制这些产品,因此我不会详细解释这些产品是什么。
很可能在你的情况下,你可以完全移除它们 将该代码通读几遍,您应该能够了解
NSXMLParser
为您做了什么以及它对您的期望
祝你好运。当使用
NSXMLParser
时,创建对象结构完全取决于你自己,因为NSXMLParser
是一个哑巴(我不是说它没有功能,我是说它把所有聪明的东西都留给你了)
NSXMLParser
只需逐行读取文件,并告诉您在当前解析的行中找到了什么(在-foundCharacters
方法中)。
它不会告诉您以前的行或即将到来的行
我将为您提供最基本的代码,这些代码将基于解析的XML结构创建对象层次结构
根据您当前的需求,您可以使这变得更容易或更具识别力
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
attributes:(NSDictionary *)attributeDict
{
//NSLog(@"started element %@", elementName);
if(resultString) {
if(eliminateWhiteSpace)
[[objects objectAtIndex:[objects count] - 1] setStringValue:[resultString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
else
[[objects objectAtIndex:[objects count] - 1] setStringValue:resultString];
resultString = nil;
}
XMLNode* currentObject = [[XMLNode alloc] init];
if(!objects) {
objects = [[NSMutableArray alloc] init];
}
[objects addObject:currentObject];
[currentObject setNodeName:elementName];
if([[attributeDict allKeys] count] > 0) {
currentObject.attributes = attributeDict;
}
}
这里有几个类变量和一个
XMLNode
类。您必须根据自己的需要定制这些产品,因此我不会详细解释这些产品是什么。
很可能在你的情况下,你可以完全移除它们 将该代码通读几遍,您应该能够了解
NSXMLParser
为您做了什么以及它对您的期望
祝你好运。看来你从未重置过
标题
或链接
试试这个(不确定,因为你的逻辑有点与众不同)
似乎您从未重置过
标题
或链接
试试这个(不确定,因为你的逻辑有点与众不同)
注意:不是最优化的解决方案,但应该可以工作(稍后我将编辑此内容)
注意:不是最优化的解决方案,但应该可以工作(稍后我将编辑此内容)
请发布您的
didEnd
代码。这是您应该处理关闭最后一个对象的地方。如果你不关闭最后一个对象并创建一个新对象,那么你只是在创建一个大对象,所有数据都混在一起。谢谢,我已经附加了它。你能发布你试图解析的实际XML吗?请发布你的didEnd
代码。这是您应该处理关闭最后一个对象的地方。如果你不关闭最后一个对象并创建一个新对象,那么你只是在创建一个大对象,所有数据都混在一起。谢谢,我已经附加了它。你能发布你试图解析的实际XML吗?这给了我一个表,每个单元格中都有空字符串。谢谢,但还是空单元格。@Robert:hm。。让我们稍后再看你的具体案例,现在,我将发布另一个答案,用一种许多人普遍认为的方式follow@Robert:发布了一个新的答案(我身边没有我的mac电脑,但我认为它应该可以工作)。我将在稍后编辑这两个答案,以使其正确(也许明天),但希望你应该正确track@Robert:我也更新了这个答案。(如果你坚持你原来的逻辑,那么这个答案在技术上应该是有效的……多亏了@Putz1103)这给了我一个表格,每个单元格都有空字符串。谢谢,但还是空单元格。@Robert:hm。。让我们稍后再看你的具体案例,现在,我将发布另一个答案,用一种许多人普遍认为的方式follow@Robert:发布了一个新的答案(我身边没有我的mac电脑,但我认为它应该可以工作)。我将在稍后编辑这两个答案,以使其正确(也许明天),但希望你应该正确track@Robert:我也更新了这个答案。(如果你坚持你原来的逻辑,那么这个答案在技术上应该是有效的…感谢@Putz1103)谢谢,但是与[\uu NSArrayM insertObject:atIndex:]:object不能是nil
Mea culpa,我只需要添加element=elementName代码>到didStartElement的顶部
。非常感谢,先生。@罗伯特:噢。。。嘘。这表明现代IDE如何帮助我们忽略这些无关紧要的细节。事实上。。。更新答案。不需要element=elementName代码>谢谢,但是崩溃了[\uu NSArrayM insertObject:atIndex:]:对象不能为零
Mea culpa,我只需要添加element=elementName代码>到didStartElement的顶部
。非常感谢,先生。@罗伯特:噢。。。嘘。这表明现代IDE如何帮助我们忽略这些无关紧要的细节。事实上。。。更新答案。不需要元素
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
{
//NSLog(@"ended element %@", elementName);
if(resultString) {
if(eliminateWhiteSpace)
[[objects objectAtIndex:[objects count] - 1] setStringValue:[resultString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
else
[[objects objectAtIndex:[objects count] - 1] setStringValue:resultString];
}
if([objects count] > 1) {
[[objects objectAtIndex:[objects count] - 2] addSubNode:[objects objectAtIndex:[objects count] - 1]];
[objects removeObjectAtIndex:[objects count] - 1];
}
resultString = nil;
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:@"item"]) {
[feeds addObject:[item copy]];
}
if ([elementName isEqualToString:@"title"]) {
[item setObject:[title copy] forKey:@"title"];
title = @"";
}
if ([elementName isEqualToString:@"link"]) {
[item setObject:[link copy] forKey:@"link"];
link = @"";
}
}
for (NSString* feedString in [[NSUserDefaults standardUserDefaults] objectForKey:@"RSSFeeds"])
{
NSURL *url = [NSURL URLWithString:feedString];
parser = [[NSXMLParser alloc] initWithContentsOfURL:url];
[parser setDelegate:self];
[parser setShouldResolveExternalEntities:NO];
[parser parse];
//declare "NSMutableString *strCurrent;" in the .h of this class
strCurrent = [NSMutableString alloc] init];
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
[strCurrent appendString:string];
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
attributes:(NSDictionary *)attributeDict
{
if ([elementName isEqualToString:@"item"]) {
item = [[NSMutableDictionary alloc] init];
}
if ([elementName isEqualToString:@"title"]) {
strCurrent = [[NSMutableString alloc] init];
}
if ([elementName isEqualToString:@"link"]) {
strCurrent = [[NSMutableString alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:@"title"]) {
[item setObject:strCurrent forKey:@"title"];
}
if ([elementName isEqualToString:@"link"]) {
[item setObject:strCurrent forKey:@"link"];
}
if ([elementName isEqualToString:@"item"]) {
[feeds addObject:[item copy]];
}
}