Extracting name of RSS feed in Cocoa-Touch
I am trying to parse an RSS XML feed. I have figured out how to parse what's in the tags for the individual stories, but I cannot figure out how to get the name of the entire feed (for example "CNN's News Feed"). I think it's in and I've tried a ton of things but I can't figure it out. Below is part of my parsing code that I think what seemed like the most sense, but didn't work. Can anyone help?
Thanks!! GL
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
currentElement = [elementName copy];
if ([elementName isEqualToString:@"item"] || [elementName isEqualToString:@"channel"]) {
item = [[NSMutableDictionary alloc] init];
currentTitle = [[NSMutableString alloc] init];
currentDate = [[NSMutableString alloc] init];
currentSummary = [[NSMutableString alloc] init];
currentLink = [[NSMutableString alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
if ([elementName isEqualToString:@"channel"]) {
// save values to an item, then store that item into the array...
[item setObject:currentTitle forKey:@"title"];
[item setObject:currentLink forKey:@"link"];
[item setObject:currentSummary forKey:@"summary"];
[item setObject:currentDate forKey:@"date"];
[feedsArray addObject:[item copy]];
}
if ([elementName isEqualToString:@"item"]) {
[item setObject:currentTitle forKey:@"title"];
[item setObject:currentLink forKey:@"link"];
[item setObject:currentSummary forKey:@"summary"];
[item setObject:currentDate forKey:@"date"];
[stories addObject:[item copy]];
NSLog(@"adding story: %@", currentTitle);
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
if 开发者_如何学编程([currentElement isEqualToString:@"title"]) {
[currentTitle appendString:string];
} else if ([currentElement isEqualToString:@"link"]) {
[currentLink appendString:string];
} else if ([currentElement isEqualToString:@"description"]) {
[currentSummary appendString:string];
} else if ([currentElement isEqualToString:@"pubDate"]) {
[currentDate appendString:string];
}
}
The feed name is always included in the name of title by " - " at the end. Now if you want to get the feed name you can do it like.
NSDictionary *feedDict = [feedArray objectAtIndex:indexPath.row];
UILabel *lbl = (UILabel *)[cell.contentView viewWithTag:1];
NSArray *tempArr = [[NSArray alloc] initWithArray:[[feedDict valueForKey:@"title"] componentsSeparatedByString:@" - "]];
[lbl setText:[tempArr objectAtIndex:0]];
So you will see the name of feed in the lable.
Hope this helps.
Thanks,
Madhup
The feeds title lays outside items
and channels
so you should also trigger for a title
in didStartElement
. You also might need to make some logic to differentiate between titles
within items
and channels
and the global title
.
Let's have a try to fix it...(also noticed some possible memory leaks)
Not tested
- (void)parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
attributes:(NSDictionary *)attributeDict {
if (currentElement)
[currentElement release];
currentElement = [elementName copy];
if ([elementName isEqualToString:@"item"] ||
[elementName isEqualToString:@"channel"]) {
if (item)
[item release];
item = [[NSMutableDictionary alloc] init];
currentTitle = [[NSMutableString alloc] init];
currentDate = [[NSMutableString alloc] init];
currentSummary = [[NSMutableString alloc] init];
currentLink = [[NSMutableString alloc] init];
} else if (!item && [elementName isEqualToString:@"title"]) {
[currentElement release];
currentElement = [@"<GlobalTitle>" copy];
}
}
- (void)parser:(NSXMLParser *)parser
didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName {
if ([elementName isEqualToString:@"channel"]) {
// save values to an item, then store that item into the array...
[item setObject:currentTitle forKey:@"title"];
[item setObject:currentLink forKey:@"link"];
[item setObject:currentSummary forKey:@"summary"];
[item setObject:currentDate forKey:@"date"];
[feedsArray addObject:item]; // item will be retained by array
[item release];
[currentTitle release]; // these are also retained by the dictionary
[currentLink release];
[currentSummary release];
[currentDate release];
item = nil;
currentTitle = nil;
currentLink = nil;
currentSummary = nil;
currentDate = nil;
}
if ([elementName isEqualToString:@"item"]) {
[item setObject:currentTitle forKey:@"title"];
[item setObject:currentLink forKey:@"link"];
[item setObject:currentSummary forKey:@"summary"];
[item setObject:currentDate forKey:@"date"];
[stories addObject:item]; // item will be retained by array
[item release];
[currentTitle release]; // these are also retained by the dictionary
[currentLink release];
[currentSummary release];
[currentDate release];
item = nil;
currentTitle = nil;
currentLink = nil;
currentSummary = nil;
currentDate = nil;
NSLog(@"adding story: %@", currentTitle);
}
}
- (void)parser:(NSXMLParser *)parser
foundCharacters:(NSString *)string {
if ([currentElement isEqualToString:@"title"]) {
[currentTitle appendString:string];
} else if ([currentElement isEqualToString:@"link"]) {
[currentLink appendString:string];
} else if ([currentElement isEqualToString:@"description"]) {
[currentSummary appendString:string];
} else if ([currentElement isEqualToString:@"pubDate"]) {
[currentDate appendString:string];
} else if ([currentElement isEqualToString:@"<GlobalTitle>"]) {
self.feedTitle = string; // The feeds title is saved here
}
}
I've released an open source RSS/Atom Parser for iPhone and it makes reading and parsing web feeds extremely easy.
You can set it to read just the feed info (title, summary, etc) if you want. Checkout the documentation and play around with the demo app. Hope this helps!
精彩评论