Search code examples
xcodexml-parsingnsxmlparsernsxmlnsxmlelement

NSXMLParser can't parse special characters (accents)


I'm using NSXMLParser to parse an xml from a url (my code is almost exactly the same as here)

Some of the elements contain special characters like "á" which causes a word lik ándre to split into two (á and ndre).

Here is my loadXMLByURL

-(id) loadXMLByURL:(NSString *)urlString{
tickets     = [[NSMutableArray alloc] init];
NSURL *url      = [NSURL URLWithString:urlString];
NSData  *data   = [[NSData alloc] initWithContentsOfURL:url];
parser          = [[NSXMLParser alloc] initWithData:data];
parser.delegate = self;
[parser parse];
return self;}

I'm pretty sure it's because the encoding is not set (I think it needs to be NSUTF8StringEncoding) but I'm not sure where/how to apply it.

[UPDATE] Rest of my code...

- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{    
    if ([elementname isEqualToString:@"ticket"]) 
    {
        currentTicket = [Ticket alloc];
    }

}

- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    if ([elementname isEqualToString:@"name"]) 
    {
        currentTicket.name = currentNodeContent;
    }
    else if ([elementname isEqualToString:@"title"]) 
    {
        currentTicket.title = currentNodeContent;
    }
    else if ([elementname isEqualToString:@"status"]) 
    {
        currentTicket.status = currentNodeContent;
    }
    else if ([elementname isEqualToString:@"ticket"])
    {
        [tickets addObject:currentTicket];
        [currentTicket release];
        currentTicket = nil;
        [currentNodeContent release];
        currentNodeContent = nil;
    }

}

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

[UPDATE 2] Sample xml...

<RB>
    <list>
        <ticket>
            <name>Andrew Ford</name>
            <title>3rd release</title>
            <status>1</status>
        </ticket>

        <ticket>
            <name>David Jenkins</name>
            <title>3rd release</title>
            <status>0</status>
        </ticket>

        <ticket>
            <name>Luis gomez ándre</name>
            <title>3rd release</title>
            <status>1</status>
        </ticket>
    </list>
</RB>

Solution

  • I would load the url to an NSString and then convert like this.

    -(id) loadXMLByURL:(NSString *)urlString{
    
        tickets     = [[NSMutableArray alloc] init];
        NSURL *url      = [NSURL URLWithString:urlString];
        NSError *error;
        NSString * dataString = [[NSString alloc] initWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error];
        NSData *data = [dataString dataUsingEncoding:NSUTF8StringEncoding];
        parser          = [[NSXMLParser alloc] initWithData:data];
        parser.delegate = self;
        [parser parse];
        return self;
    
    }
    

    EDIT: Part of the problem may be that your parser:foundCharacters: method is assigning to your currentNodeContent instead of appending. See the Apple Doc at the following link.

    http://developer.apple.com/library/ios/#documentation/cocoa/reference/NSXMLParserDelegate_Protocol/Reference/Reference.html

    From the doc:

    Because string may be only part of the total character content for the current element, you should append it to the current accumulation of characters until the element changes.