Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Interface 2, Advanced iOS
Mockup & Code Gen
($9.99)

Make your own iPhone apps
and run them live!
(free)

Pic Frame Dynamo: Photo Editing
($0.99)

Abiliator
($1.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Development

Reply
 
LinkBack Thread Tools Display Modes
Old 02-17-2010, 11:23 AM   #1 (permalink)
Registered Member
 
Join Date: Feb 2010
Posts: 7
mansi5 is on a distinguished road
Default Parsing an xml using NSXMLParser

Hi there!

I'm new to coding with Obj C and on the iPhone SDK. I'm having a little trouble understanding how NSXMLParser works. I used this NSXMLParser Simple Problem - Mac Forums as an example.

Basically I have an xml file that looks like this:

Code:
<?xml version="1.0" encoding="windows-1250"?>
<RootElement>
  <State>
    <Name>Arizona</Name>
    <Time>6 a.m.ñ2 a.m.</Time>
    <Time>6 a.m.</Time>
	<Notes>This is a note for Ar</Notes>
  </State>
  <State>
    <Name>California</Name>
    <Time>CA Time.</Time>
    <Time>CA Time2.</Time>
    <Notes>This is a note for California</Notes>
  </State>
</RootElement>
I'm trying to load this xml file from awakeAtNib, and load an NSMutableDictionary with key as name of each state, and value as an array containing all the values for time, time and notes.

When I actually do [xmlParser parse], nothing happens! Am I supposed to override the "parse" method somewhere?

Since it did not do anything, I explicitly called the two parser methods.
My delegate code looks like this:

Code:
//  XMLParserAppDelegate.m
//  XMLParser
//
//  Created by Mansi Gandhi on 2/16/10.
//  Copyright __MyCompanyName__ 2010. All rights reserved.
//

#import "XMLParserAppDelegate.h"

@implementation XMLParserAppDelegate

@synthesize window;


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

    // Override point for customization after application launch
    [window makeKeyAndVisible];
}

- (void)awakeFromNib 
{
    NSLog(@"Awake from Nib");
	NSString *filePath = [[NSString stringWithString:@"~/Desktop/Sample.xml"]stringByStandardizingPath];
	[self parseXMLFile:filePath];
	
}
- (void)dealloc {
    [window release];
    [super dealloc];
}

- (void)parseXMLFile:(NSString *)pathToFile {
    BOOL success;
	
    NSURL *xmlURL = [NSURL fileURLWithPath:pathToFile];
    if (xmlParser) 
        [xmlParser release];
	
	xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL];
    [xmlParser setDelegate:self];
    [xmlParser setShouldResolveExternalEntities:YES];
    
	success = [xmlParser parse]; 
	[self parser:xmlParser didStartElement:@"RootElement"  attributes:dictionary];
	[self parser:xmlParser didEndElement:@"RootElement"];
	NSLog(@"End parsing!");
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName attributes:(NSDictionary *)attributeDict 
{
	
	if ( [elementName isEqualToString:@"RootElement"]) {
		NSLog(@"found rootelement");
		[self parser:xmlParser didStartElement:@"State"  attributes:dictionary];
		return;
    }
	
	if ( [elementName isEqualToString:@"State"] ) {
		NSLog(@"found state");
        return;
    }
	if ( [elementName isEqualToString:@"Name"] ) {
		NSLog(@"found name");
        return;
    }
	if ( [elementName isEqualToString:@"Time"] ) {
		NSLog(@"found time");
        return;
    }
	if ( [elementName isEqualToString:@"Notes"] ) {
		NSLog(@"found notes");
        return;
    }
	
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
	NSLog(@"found characters:%@",string);
        //Dont know what to do here!
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName  
{
	if ([elementName isEqualToString:@"RootElement"]) {
		NSLog(@"rootelement entering...");
	}
	if ([elementName isEqualToString:@"State"]) {
		NSLog(@"state entering...");
	}
	if ([elementName isEqualToString:@"Name"]) {
		NSLog(@"name entering...");
	}
	if ([elementName isEqualToString:@"Time"]) {
		NSLog(@"time entering...");
	}
	if ([elementName isEqualToString:@"Notes"]) {
		NSLog(@"notes entering...");
	}
}
@end

I don't know where I can get the value for that element. Like how do I get "CA Time." for <Time> under California, and then put it into a NSMutable Array.

Also, the way I call it obviously doesn't recurse for each state.

Any help is appreciated!

Thanks

Mansi
mansi5 is offline   Reply With Quote
Old 02-17-2010, 12:22 PM   #2 (permalink)
Senior Member
iPhone Dev SDK Supporter
 
Join Date: Aug 2008
Location: Memphis, TN, USA
Age: 24
Posts: 3,983
smithdale87 is on a distinguished road
Send a message via AIM to smithdale87
Default

look at the NSXMLParserDelegate protocol methods.

You'll need to implement methods such as
Code:
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict

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

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
smithdale87 is offline   Reply With Quote
Old 02-17-2010, 01:05 PM   #3 (permalink)
Registered Member
 
Join Date: Mar 2009
Posts: 117
stuffradio is on a distinguished road
Default

Like smithdale87 said, I have the following methods for iterating through the xml document.

Code:
- (void)parserDidStartDocument:(NSXMLParser *)parser
{
}

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

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

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
  namespaceURI:(NSString *)namespaceURI
 qualifiedName:(NSString *)qName{
	
}
In didStartElement you initialize the items such as your dictionary, and any other variable you'll use to capture a string or any other value.

With foundCharacters, when it catches that value of the character it found, append the string to the variables.

When it gets to didEndElement, set the Object and give it a key then add the row to your dictionary.

Hope this helps!
stuffradio is offline   Reply With Quote
Old 02-17-2010, 02:20 PM   #4 (permalink)
Registered Member
 
Join Date: Feb 2010
Posts: 7
mansi5 is on a distinguished road
Default

Hi,

I get that the below methods are for NSXMLParserDelegate

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

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

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
But when I set
[xmlParser setDelegate:self];
and then call
[xmlParser parse], is this supposed to call its delegate methods?

I mean, where are these delegate methods being called?

Sorry about my ingnorance
mansi5 is offline   Reply With Quote
Old 02-17-2010, 02:48 PM   #5 (permalink)
Registered Member
 
Join Date: Mar 2009
Posts: 117
stuffradio is on a distinguished road
Default

Quote:
Originally Posted by mansi5 View Post
Hi,

I get that the below methods are for NSXMLParserDelegate

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

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

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
But when I set
[xmlParser setDelegate:self];
and then call
[xmlParser parse], is this supposed to call its delegate methods?

I mean, where are these delegate methods being called?

Sorry about my ingnorance
Yes, xmlParser parse does call the methods.
stuffradio is offline   Reply With Quote
Old 02-17-2010, 03:55 PM   #6 (permalink)
Registered Member
 
Join Date: Feb 2010
Posts: 7
mansi5 is on a distinguished road
Default

Quote:
Originally Posted by stuffradio View Post
Yes, xmlParser parse does call the methods.
Oh, ok. Let me give it a shot then.
Thanks!
mansi5 is offline   Reply With Quote
Old 02-17-2010, 10:16 PM   #7 (permalink)
Registered Member
 
Join Date: Feb 2010
Posts: 7
mansi5 is on a distinguished road
Default

Quote:
Originally Posted by stuffradio View Post
Yes, xmlParser parse does call the methods.
Hi,

I created a simple version of calling the delegate methods,

So now my .m file looks like:

Code:
//  XMLParserAppDelegate.m
//  XMLParser
//
//  Created by Mansi Gandhi on 2/16/10.
//  Copyright __MyCompanyName__ 2010. All rights reserved.
//

#import "XMLParserAppDelegate.h"

@implementation XMLParserAppDelegate

@synthesize window;


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

    // Override point for customization after application launch
    [window makeKeyAndVisible];
}

- (void)awakeFromNib 
{
    NSLog(@"Awake from Nib");
	NSString *filePath = [[NSString stringWithString:@"~/Desktop/Sample.xml"]stringByStandardizingPath];
	[self parseXMLFile:filePath];
	
}
- (void)dealloc {
    [window release];
    [super dealloc];
}

- (void)parseXMLFile:(NSString *)pathToFile {
    BOOL success;
	
    NSURL *xmlURL = [NSURL fileURLWithPath:pathToFile];
    if (xmlParser) 
        [xmlParser release];
	
    xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL];
    [xmlParser setDelegate:self];
    
	success = [xmlParser parse]; 
	NSLog(@"End parsing!");
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{
	NSLog(@"Did start element");
	if ( [elementName isEqualToString:@"RootElement"]) {
				NSLog(@"found rootElement");
			return;
		}
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
	NSLog(@"Did end element");
	if ([elementName isEqualToString:@"RootElement"]) {
				NSLog(@"rootelement end");
		}
		
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
	NSLog(@"Did fine characters");
}
But none of the log statements get printed => the delegate methods did not get called. Am I missing something?

Thanks again!
mansi5 is offline   Reply With Quote
Old 02-17-2010, 10:45 PM   #8 (permalink)
Registered Member
 
Join Date: Mar 2009
Posts: 117
stuffradio is on a distinguished road
Default

Quote:
Originally Posted by mansi5 View Post
Hi,

I created a simple version of calling the delegate methods,

So now my .m file looks like:

Code:
//  XMLParserAppDelegate.m
//  XMLParser
//
//  Created by Mansi Gandhi on 2/16/10.
//  Copyright __MyCompanyName__ 2010. All rights reserved.
//

#import "XMLParserAppDelegate.h"

@implementation XMLParserAppDelegate

@synthesize window;


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

    // Override point for customization after application launch
    [window makeKeyAndVisible];
}

- (void)awakeFromNib 
{
    NSLog(@"Awake from Nib");
	NSString *filePath = [[NSString stringWithString:@"~/Desktop/Sample.xml"]stringByStandardizingPath];
	[self parseXMLFile:filePath];
	
}
- (void)dealloc {
    [window release];
    [super dealloc];
}

- (void)parseXMLFile:(NSString *)pathToFile {
    BOOL success;
	
    NSURL *xmlURL = [NSURL fileURLWithPath:pathToFile];
    if (xmlParser) 
        [xmlParser release];
	
    xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL];
    [xmlParser setDelegate:self];
    
	success = [xmlParser parse]; 
	NSLog(@"End parsing!");
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{
	NSLog(@"Did start element");
	if ( [elementName isEqualToString:@"RootElement"]) {
				NSLog(@"found rootElement");
			return;
		}
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
	NSLog(@"Did end element");
	if ([elementName isEqualToString:@"RootElement"]) {
				NSLog(@"rootelement end");
		}
		
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
	NSLog(@"Did fine characters");
}
But none of the log statements get printed => the delegate methods did not get called. Am I missing something?

Thanks again!
You need to allocate an xmlParser and I don't think the simulator can read your hard drive, maybe I'm wrong though?
stuffradio is offline   Reply With Quote
Old 02-19-2010, 08:10 PM   #9 (permalink)
Registered Member
 
Join Date: Feb 2010
Posts: 7
mansi5 is on a distinguished road
Default

Quote:
Originally Posted by stuffradio View Post
You need to allocate an xmlParser and I don't think the simulator can read your hard drive, maybe I'm wrong though?
Got it to work! Thanks so much
mansi5 is offline   Reply With Quote
Old 02-20-2010, 09:44 AM   #10 (permalink)
Registered Member
 
Join Date: Jan 2009
Location: Atlanta
Posts: 411
funkytaco is on a distinguished road
Default

Quote:
Originally Posted by stuffradio View Post
You need to allocate an xmlParser and I don't think the simulator can read your hard drive, maybe I'm wrong though?
Code:
- (XMLParser *) initXMLParser {
	
	[super init];
	
	appDelegate = ( MyAppDelegate *)[[UIApplication sharedApplication] delegate];
	
	return self;
}
I think that's what he was missing.
funkytaco is offline   Reply With Quote
Old 01-12-2012, 04:34 AM   #11 (permalink)
Registered Member
 
Join Date: Jan 2012
Posts: 9
Aalok is on a distinguished road
Default

Quote:
great tutorial
thanks for this
Aalok is offline   Reply With Quote
Reply

Bookmarks

Tags
nsxmlparser, xml parser

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



» Advertisements
» Online Users: 329
5 members and 324 guests
2Apps1Day, akacaj, SLIC, soohyun, Techgirl-52
Most users ever online was 1,387, 04-10-2012 at 04:21 AM.
» Stats
Members: 175,650
Threads: 94,115
Posts: 402,887
Top Poster: BrianSlick (7,990)
Welcome to our newest member, soohyun
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 10:07 PM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0