Search code examples
iphoneiosxmlxml-parsingnsxmlparser

XML Parse not showing elements with & symbol inside


Im trying to parse a xml feed in my app... The xml file is in this url

feeds.feedburner.com/blogspot/TUvAW?format=xml

The problem is that when I access the description segment it diplays different special symbols such as quotation marks. This is one of the descripton segments im trying to parse from my xml:

<description>Este es mi blog 3&lt;img src="http://feeds.feedburner.com/~r/blogspot/TUvAW/~4/URCV9ModTR0" height="1" width="1"/&gt;</description>

Im parsing it with the NSXMLParser, these are the method I'm using in my:

XMLParser.m

- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    currentNodeContent = (NSMutableString *) [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}

- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
    if ([elementname isEqualToString:@"item"])
    {
        currentFeed = [Feed alloc];
        isStatus = YES;
    }
    if ([elementname isEqualToString:@"author"])
    {
        isStatus = NO;
    }
}

- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    if (isStatus)
    {
        if ([elementname isEqualToString:@"description"])
        {
            currentFeed.description = currentNodeContent;
            NSLog(@"%@",currentNodeContent);

        }
        if ([elementname isEqualToString:@"title"])
        {
            currentFeed.content = currentNodeContent;
            NSLog(@"%@",currentNodeContent);

        }
        if ([elementname isEqualToString:@"link"])
        {
            currentFeed.WVUrl = currentNodeContent;
            NSLog(@"%@",currentNodeContent);
        }
    }
    if ([elementname isEqualToString:@"item"])
    {
        [self.feeds addObject:currentFeed];
        currentFeed = nil;
        currentNodeContent = nil;
    }
}

Im using those NSLogs to track the strings that Im getting from the parse but my description node content is always showing just this : > The title and link nodes are displaying perfectly.

I want to get all that string from the description node to use it later but simply I can't, I dont know whats going wrong with this.


Solution

  • The problems have been outlined by Abhishek, Rob and me. But I think it's worth to summarize it and show the correct solution.

    The main problem is that parser:foundCharacters: is called several times for the <description> tag, each call providing a piece of the description.

    The solution is to concatenate the pieces:

    XMLParser.h:

    NSMutableString* currentNodeContent;
    

    XMLParser.m:

    - (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
    {
        if (currentNodeContent == nil)
            currentNodeContent = [[NSMutableString alloc] initWithCapacity: 20];
        [currentNodeContent appendString: [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
    }
    
    - (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
    {
        if ([elementname isEqualToString:@"item"])
        {
            currentFeed = [Feed alloc];
            isStatus = YES;
        }
        if ([elementname isEqualToString:@"author"])
        {
            isStatus = NO;
        }
    }
    
    - (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
    {
        if (isStatus)
        {
            if ([elementname isEqualToString:@"description"])
            {
                currentTweet.description = currentNodeContent;
                NSLog(@"%@",currentNodeContent);
    
            }
            if ([elementname isEqualToString:@"title"])
            {
                currentTweet.content = currentNodeContent;
                NSLog(@"%@",currentNodeContent);
    
            }
            if ([elementname isEqualToString:@"link"])
            {
                currentFeed.WVUrl = currentNodeContent;
                NSLog(@"%@",currentNodeContent);
            }
        }
        if ([elementname isEqualToString:@"item"])
        {
            [self.feeds addObject:currentFeed];
            currentFeed = nil;
            [currentNodeContent release];
            currentNodeContent = nil;
        }
    }