Parsing an XML file

This is the “XMLParsing” example. In this app we will read data from xml file and display the data on the screen.

Step 1: Open the Xcode and create a new Xcode project using Navigation base application template. Give the application name “XML”. As shown in the figure below:

Step 2: Expand classes and notice Interface Builder created the RootViewController.h and RootViewController.m class for you. Expand Resources and notice the template generated a separate nib, RootViewController.xib.

Step 3: We need to add another file. Right-click on the Classes folder and choose Add -> New File. Under Cocoa Touch Class category choose Objective-C class. Name it Book.h and Book.m file.
This will be a very simple class that will take our dummy data file, read it in as an NSArray and provide some utility methods to access the data from the file.

#import <uikit/UIKit.h>
@interface Book : NSObject {

	NSInteger bookID;
	NSString *name;	//Same name as the Entity Name.
	NSString *address;	//Same name as the Entity Name.
	NSString *country;	//Same name as the Entity Name.

}

@property (nonatomic, readwrite) NSInteger bookID;
@property (nonatomic, retain) NSString *name;
@property (nonatomic, retain) NSString *address;
@property (nonatomic, retain) NSString *country;

@end

Step 4: We need to add Book.m file.

#import "Book.h"
@implementation Book

@synthesize name, address, country, bookID;
- (void) dealloc {

	[country release];
	[address release];
	[name release];
	[super dealloc];
}
@end

Step 5: We need to add another file. Right-click on the Resource folder and choose Add -> New File. Under Resource category choose View-XIB class. Name it BookDetailView.xib file. Double click the file and select Grouped table view.

Step 6: We need to add another file. Right-click on the Classes folder and choose Add -> New File. Under Cocoa Touch Class category choose Objective-C class. Name it XMLParser.h and XMLParser.m file. This will be a very simple class that will take our dummy data file, read it in as an NSArray and provide some utility methods to access the data from the file.

#import <uikit/UIKit.h>

@class XMLAppDelegate, Book;

@interface XMLParser : NSObject {

	NSMutableString *currentElementValue;

	XMLAppDelegate *appDelegate;
	Book *aBook;
}

- (XMLParser *) initXMLParser;

@end

Step 7: We need to open XMLParser.m file.

#import "XMLParser.h"
#import "XMLAppDelegate.h"
#import "Book.h"

@implementation XMLParser

- (XMLParser *) initXMLParser {

	[super init];

	appDelegate = (XMLAppDelegate *)[[UIApplication sharedApplication] delegate];

	return self;
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
  namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName
	attributes:(NSDictionary *)attributeDict {

	if([elementName isEqualToString:@"Books"]) {
		//Initialize the array.
		appDelegate.books = [[NSMutableArray alloc] init];
	}
	else if([elementName isEqualToString:@"Book"]) {

		//Initialize the book.
		aBook = [[Book alloc] init];

		//Extract the attribute here.
		aBook.bookID = [[attributeDict objectForKey:@"id"] integerValue];

		NSLog(@"Reading id value :%i", aBook.bookID);
	}

	NSLog(@"Processing Element: %@", elementName);
}

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

	if(!currentElementValue)
		currentElementValue = [[NSMutableString alloc] initWithString:string];
	else
		[currentElementValue appendString:string];

	NSLog(@"Processing Value: %@", currentElementValue);

}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
  namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {

	if([elementName isEqualToString:@"Books"])
		return;

	//There is nothing to do if we encounter the Books element here.
	//If we encounter the Book element howevere, we want to add the book object to the array
	// and release the object.
	if([elementName isEqualToString:@"Book"]) {
		[appDelegate.books addObject:aBook];

		[aBook release];
		aBook = nil;
	}
	else
		[aBook setValue:currentElementValue forKey:elementName];

	[currentElementValue release];
	currentElementValue = nil;
}

- (void) dealloc {

	[aBook release];
	[currentElementValue release];
	[super dealloc];
}

@end

Step 8: We need to add another file. Right-click on the Classes folder and choose Add -> New File. Under Cocoa Touch Class category choose UIViewController class. Name it BookDetailViewController.h and BookDetailViewController.m file.

#import <uikit/UIKit.h>

@class Book;

@interface BookDetailViewController : UIViewController {

	IBOutlet UITableView *tableView;

	Book *aBook;
}

@property (nonatomic, retain) Book *aBook;

@end

Step 9: We need to open BookDetailViewController.m file.

- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
    }
	switch(indexPath.section)
	{
		case 0:
			cell.text = aBook.name;
			break;
		case 1:
			cell.text = aBook.address;
			break;
		case 2:
			cell.text = aBook.country;
			break;
	}
	return cell;
}

- (NSString *)tableView:(UITableView *)tblView titleForHeaderInSection:(NSInteger)section {

	NSString *sectionName = nil;

	switch(section)
	{
		case 0:
			sectionName = [NSString stringWithString:@"Name"];
			break;
		case 1:
			sectionName = [NSString stringWithString:@"Address"];
			break;
		case 2:
			sectionName = [NSString stringWithString:@"Country"];
			break;
	}
	return sectionName;
}

Step 10: We need to open XmlAppDelegate.h file.

#import <uikit/UIKit.h>

@interface XMLAppDelegate : NSObject <uiapplicationDelegate> {

    UIWindow *window;
    UINavigationController *navigationController;

	NSMutableArray *books;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UINavigationController *navigationController;

@property (nonatomic, retain) NSMutableArray *books;

@end

Step 11: We need to open XmlAppDelegate.m file.

#import "XMLAppDelegate.h"
#import "RootViewController.h"
#import "XMLParser.h"

@implementation XMLAppDelegate

@synthesize window;
@synthesize navigationController, books;


- (void)applicationDidFinishLaunching:(UIApplication *)application {


	NSURL *url = [[NSURL alloc] initWithString:@"http://www.edumobile.org/blog/uploads/XML-parsing-data/Data.xml"];
	NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];

	//Initialize the delegate.
	XMLParser *parser = [[XMLParser alloc] initXMLParser];

	//Set delegate
	[xmlParser setDelegate:parser];

	//Start parsing the XML file.
	BOOL success = [xmlParser parse];

	if(success)
		NSLog(@"No Errors");
	else
		NSLog(@"Error Error Error!!!");

	// Configure and show the window
	[window addSubview:[navigationController view]];
	[window makeKeyAndVisible];
}

Step 12: Now build and run the code and view the Output in the Simulator.

You can download source code from here XML

  • Rick
  • April 15, 2011
  • iOS

About the Author

Leave a Reply 12 comments

abuyaqeen - April 15, 2011 Reply

thank you very much ..

Patrick - April 17, 2011 Reply

Thanks!

J.L.G - May 7, 2011 Reply

thanks for such tutorial.

i have a couple questions. is there any way to contact you directly?

Pulkit - May 10, 2011 Reply

Thanks you for putting this together.

I followed the tutorial closely and the following lines were the only ones missing (in BookDetailViewController.m) that weren’t mentioned explicitly and prevented me from building the code:
#import “Book.h”
@synthesize aBook;

… After I downloaded your source, I was able to peek inside and resolve this. But the build didn’t show the expected visual output. It seems the older auto project generated root view controller was still hooked up to the window. I didn’t have the motivation to dig deeper into the source as I’m a beginner but it would be fantastic if you could actively talk about how to clean up the auto-generated views and wire up the one in your tutorial to an actual window :)

Brad Robinson - May 14, 2011 Reply

Hi

Great tutorial but i just had one question, i would like to show an image either in the current detail view or in a new detail view possibly accessed by a button at the bottom of the current view any help would be much appreciated.

If you think that the button at the bottom is the best idea i would like the url for the image loaded into the button from the xml data on the internet.

As i said i would really appreciate the help as i am still a beginner and would like to be able to complete this app.

Thanks
Brad

Ross - May 19, 2011 Reply

I changed the link in the app delegate .m file to my own XML file on the internet and now the app builds but crashes with the error “terminate called after throwing an instance of ‘NSException’ ” I’ve also tried changing the link to a different XML file on the same site with identical results. (http://chakrainteractive.com/mob/0-vin/Books.xml)

Any idea what is going on?

DonOnGuitar - June 1, 2011 Reply

The link to your XML file gives 404 error.
http://chakrainteractive.com/mob/0-vin/Data.xml

    Sushant - June 2, 2011 Reply

    i have changed the link , you can checked now and also updated the code.

      Ross - June 6, 2011 Reply

      Sushant: Just downloaded your updated code, and now the table is completely empty. Just a heads up.

        Sushant - June 9, 2011 Reply

        I have downloaded SourceCode from post and compile it. Working perfectly. You try it once again.

Leave a Reply: