Home > Techniques > A Simple Quick Reusable XML Parser For The iPhone

A Simple Quick Reusable XML Parser For The iPhone

logo

I found that I was needing an XML parser for nearly every iPhone application I was writing. Once you figure out the streaming nature of NSXMLParser, it really isn’t very difficult to use. However, since I was always having the didStartElement/foundCharacters/didEndElement functions in each application, I really wanted to break them out into a reusable class.

I found that most my XML implementations were VERY simple, as I was just using it for data storage and transfer. However, of course, each XML is different so my class has to handle that properly.

After making several iterations, I settled on using an NSArray for the root of the XML file. Each node is a NSDictionary with three object/key pairs:

  • element – This is the element name
  • data – This is the string data in the element
  • children – This is an NSArray of the children

So a basic usage would be to let it parse your XML, then walk thru the array you get back filling up your internal data structures with the information you need. You can dump the XML to the debug console with simple code like this:

NSURL *URL=[[NSURL alloc] initWithString:@"http://www.w3schools.com/XML/cd_catalog.xml"];
SimpleXMLParser* thisParser = [[SimpleXMLParser alloc] initWithURL:URL];
[URL release];
[thisParser parse];
[thisParser dumpRoot];

The dumpRoot function is implemented as two functions as so:


- (void) dumpArrayRecursive: (NSArray*) inArray parentElement:(NSString*)inParent
{
 for (int i=0;i<[inArray count];i++)
 {
 NSDictionary* thisDict = [inArray objectAtIndex:i];
 NSLog(@"Element: %@    Data:  %@    Parent:  %@", [thisDict objectForKey:@"element"], [thisDict objectForKey:@"data"], inParent);
 [self dumpArrayRecursive:[thisDict objectForKey:@"children"] parentElement:[thisDict objectForKey:@"element"] ];
 }
}

- (void) dumpRoot
{
 [self dumpArrayRecursive:theMainStack parentElement:@"Root"];
}

I am sure many improvements could be made, so feel free to be vocal in the comments section. I am fairly new to Objective-C and don't feel I have a real grasp of memory management. I am SURE I am leaking quite a bit. I figure I should be walking through the root array recursively releasing each dictionary, and each array on each dictionary. But I havn't implemented that yet...so... beware of that. Or maybe I could use some internal garbage collection to do it for me? I don't know really...any suggestions would be fantastic.

At any rate, this is a good example of a simple XML parser. No it isn't going to work in all cases, but it is reusable, so it beats re-implementing the streaming parser each time!

Here is the code:   SimpleXMLTest.zip


  1. July 28th, 2010 at 17:19 | #1

    Great post! I tried out the XML parser and it works great! I did add the following line to didStartElement in order to save the attributes:

    [newDict setObject:attributeDict forKey:@"attributes"];

    Other than that, this is very useful, thanks for posting!

  2. August 2nd, 2010 at 00:14 | #2

    Good work mate. I was looking for something similar and your solution just worked great for me.

  3. kuna
    March 22nd, 2011 at 11:45 | #3

    Doesn’t work in simulator with iOS 4.3 :(

  1. July 13th, 2011 at 01:40 | #1