views:

232

answers:

3

Hi All,

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];
    }
}
A: 

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
    }
}
epatel
A: 

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

Madhup
A: 

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!

Michael Waterfall