开发者

Parse Nested XML Objective C - NSXMLParser

开发者 https://www.devze.com 2023-03-20 11:14 出处:网络
All, I have XML in the following format: <linked-list> <Description> <desc></desc>

All,

I have XML in the following format:

<linked-list>
    <Description>
        <desc></desc>
        <IP></IP>
    </Description>
</linked-list>

This XML statement could have an infinite number of <Description></Description> inside of the <linked-list></linked-list>.

How should I parse this using NSXMLParser? My current code is as follows, but it parses incorrectly.

@implementation XMLParser

@synthesize response;

- (XMLParser *) initXMLParser
{
    self = [super init];
    // init dictionary of response data 
    response = [[NSMutableDictionary alloc] init];
    return self;
}

//Gets Start Element of SessionData
- (void)parser:(NSXMLParser *)parser 
        didStartElement:(NSString *)elementName 
        namespaceURI:(NSString *)namespaceURI 
        qualifiedName:(NSString *)qualifiedName 
        attributes:(NSDictionary *)attributeDict 
{
    if ([elementName isEqualToString:@"linked-list"])
    {
        NSLog(@"Found linked-list in the return XML! Continuing...");
        //response is a NSMutableArray instance variable

        //THIS SHOULD NEVER NEED TO BE USED
        if (!response)//if array is empty, it makes it!
        {
            NSLog(@"Dictionary is empty for some reason, creating...");
            response = [[NSMutableDictionary alloc] init];
        }
        //END: THIS SHOULD NEVER BE USED
        return;
    }
    else
    {
        currentElementName = elementName;
        NSLog(@"Current Element Name = %@", currentElementName);
        return;
    }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string 
{
    if (!currentElementValue) {
        // init the ad hoc string with the value     
        currentElementValue = [[NSMutableString alloc] initWithString:string];
    } else {
        [currentElementValue setString:string];
        NSLog(@"Processing value for : %@", string);
    }
}  

//Gets End Element of linked-list
- (void)parser:(NSXMLParser *)parser 
 didEndElement:(NSString *)elementName
  namespaceURI:(NSString *)namespaceURI 
 qualifiedName:(NSString *)qName {
    if ([elementName isEqualToString:@"linked-list"])
开发者_JAVA百科    {
        // We reached the end of the XML document
        // dumps dictionary into log
        NSLog(@"Dump:%@", [response description]);
        return;
    }
    else
    {
        //Adds key and object to dictionary
        [response setObject:currentElementValue forKey:currentElementName];
        NSLog(@"Set values, going around again... brb.");
    }
    currentElementValue = nil;
    currentElementName = nil;
}


@end


Some observations:

  1. An infinite number of WHAT inside of the WHAT?

  2. Assuming there can be more than one Description element, the outer data structure in which you store the contents must be a NSMutableArray, not a dictionary. You then use one mutable dictionary per Description element.

  3. Consequently, in didStartElement:, check if the element name is @"Description" and if so, create a new NSMutableDictionary instance that you store in an ivar.

  4. In foundCharacters:, you always have to append the new characters to the existing currentElementValue because the method can be called multiple times for each element's contents. I see many people do this wrong despite the fact that Apple's sample code clearly demonstrates the correct way.

  5. In didEndElement:, do this:

    • If the element name is @"desc" or @"IP", assign currentElementValue to the corresponding key in your current mutable dictionary. Don't forget to release currentElementValue before you set it to nil. You currently have a memory leak in your code because you're not doing that.

    • If the element name is @"Description", add the current mutable dictionary to the mutable array. Release the dictionary and set the ivar to nil. A new dictionary will be created the next time you encounter a @"Description" element in didStartElement:.

    • If the element name is @"linked-list", the mutable array will contain all the dictionaries and you're done.

0

精彩评论

暂无评论...
验证码 换一张
取 消