Iphone – Datatypes for use with NSXMLParser

cocoa-touchiphonensxmlparser

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.

Best Answer

I don't know where your code is failing, but here's the correct way to handle this:

NSMutableString *buffer = [[NSMutableString alloc] init];

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict {
    [buffer setString:@""];
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    if([elementName isEqualToString:@"number"]) {
        [aChild setNumber:[buffer intValue]];
        [buffer setString:@""];
    }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    [buffer appendString:string];
}
Related Topic