iphonecocoa-touchnsxmlparser

Datatypes for use with NSXMLParser


I'm using NSXMLParser to parse XML data from a remote server. I followed a tutorial to get up and running and everything is ok for any (NSString *) members I have in my objects that I'm creating. I also have integers that I need to set from the XML data, such as:

<root>
    <child>
        <name> Hello </name>
        <number> 123 </number>
    </child>
    <child>
        <name> World</name>
        <number> 456 </number>
    </child>
</root>

In this case I would be creating two "child" objects. I'm using:

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
      namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    ...
    [aChild setValue:currentElementValue forKey:elementName];
    ...
}

Delegate to set the values. This is where I get to my problem. The "NSString *name" member is set fine everytime, however if I use an NSInteger, then whenever I try to set "number" I get an EXC_BAD_ACCESS. So I tried using an "int" instead. But now I can't use key-value programming and need to look for the node manually:

if([elementName isEqualToString:@"number"]) {
    aChild.number = [currentElementValue intValue]
}

This is okay, I can deal with that because I know what nodes I'll be getting, but it gets worse. When currentElementValue is an "NSMutableString *" as per the tutorial, it does not return the correct integer even though the string is correct. For instance:

    NSLog(@"NSMutableString Value: %@, and intValue %d\n", currentElementValue, [currentElementValue intValue]); 
// Value will be 123 but intValue will be 0

So I made currentElementValue an NSString instead of an NSMutableString and I can get the proper intValue. But I read online that the reason it is an NSMutableString is because the:

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string

Delegate used to set the value can occur more than once, but typically does not. So my question is does anybody know what I'm doing wrong? This seems like a pretty trivial case for NSXMLParser so I'm sure it's something I'm misunderstanding.


Solution

  • Couple things going on here.

    First, you have obvious blanks in your XML character data, e.g.

            <number> 456 </number>
    

    You should really strip out that whitespace. That is likely what is causing the return value of [NSString intValue] to be wrong. If you can remove it at the source, great. If not, you can strip it out on the receiving end by doing:

    currentElementValue = [currentElementValue stringByTrimmingCharactersInSet:
        [NSCharacterSet whitespaceAndNewlineCharacterSet]];
    

    The reason you couldn't use key/value is that you can't store an NSInteger value in an NSMutableDictionary. Both keys and values in the dictionary have to descend from NSObject, and NSInteger is (I'm surmising, here) just a platform-safe typedef of int. So you should use an NSNumber instead:

    NSNumber *theInt = [NSNumber numberWithInt:[currentElementValue intValue]];
    [aChild setObject:theInt forKey:elementName];