Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

tssav

macrumors newbie
Original poster
Dec 8, 2010
2
0
Hi Folks,
I need help with parsing a xml file. My problem is I don't know how to implement the didEndElement delegate.
What I am trying to acheive is that I will have 2 cells where Old Testament and New Testament will be displayed and then the Books of the Bible and then the chapters.
If I can just get some help with the xml parsing the rest I can manage.

Will be very grateful for any help!

Thanks and regards!


My xml file is as follows:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<bible>
	<testament name="Old Testament">
		<book name="Genesis">
			<chapter id="Genesis 1"></chapter>
			<chapter id="Genesis 2"></chapter>
		</book>
		<book name="Exodus">
			<chapter id="Exodus 1"></chapter>
			<chapter id="Exodus 2"></chapter>
		</book>
	</testament>
	<testament name="New Testament">
		<book name="Matthew">
			<chapter id="Matthew 1"></chapter>
			<chapter id="Matthew 2"></chapter>
		</book>
		<book name="Revelation">
			<chapter id="Revelation 1"></chapter>
			<chapter id="Revelation 2"></chapter>
		</book>
	</testament>
</bible>
-------------------------------------------------------------------
Code:
//  Bible.h
#import <Foundation/Foundation.h>

@interface Bible : NSObject {
	NSMutableArray *bible;
	NSMutableArray *testament;
	NSMutableArray *book;
	NSString *chapterID;
	
}

@property (nonatomic, retain)NSMutableArray *bible;
@property (nonatomic, retain)NSMutableArray *testament;
@property (nonatomic, retain)NSMutableArray *book;
@property (nonatomic, retain)NSString *chapterID;

@end
------------------------------------------------------------------------
//  Bible.m

#import "Bible.h"


@implementation Bible

@synthesize bible;
@synthesize testament;
@synthesize book;
@synthesize chapterID;

- (void) dealloc {
	[bible release];
	[testament release];
	[book release];
	[chapterID release];
	[super dealloc];
}

@end
-----------------------------------------------------------------


//
//  XMLParser.h
//  BibleXML
//

#import <Foundation/Foundation.h>
#import "Bible.h"

@protocol NSXMLParserDelegate;

@class BibleXMLAppDelegate, Bible;

@interface XMLParser : NSObject <NSXMLParserDelegate> {
	
	
	NSMutableString *currentElementValue;
	
	BibleXMLAppDelegate *appDelegate;
	Bible *theBible;

}

- (XMLParser *) initXMLParser;

@end

-------------------------------------------------------------------------

//
//  XMLParser.m

#import "XMLParser.h"
#import "BibleXMLAppDelegate.h"
#import "Bible.h"


@implementation XMLParser

- (XMLParser *) initXMLParser {
	
	[super init];
	
	appDelegate = (BibleXMLAppDelegate *) [[UIApplication sharedApplication] delegate];
	return self;
}

- (void)parserDidStartDocument:(NSXMLParser *)parser{	
	NSLog(@"found file and started parsing");
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
  namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName
	attributes:(NSDictionary *)attributeDict {
	if([elementName isEqualToString:@"bible"]) {
		NSLog(@"Found element: %@", elementName);
		appDelegate.bible = [[NSMutableArray alloc] init];
	}

	else if([elementName isEqualToString:@"testament"]) {
		
		theBible = [[Bible alloc] init];
		//Extract the attribute here.
		theBible.testament = [attributeDict valueForKey:@"name"];
		NSLog(@"Testament: %@", theBible.testament);
		return;
	}
	
	else if ([elementName isEqualToString:@"book"])
	{
		theBible.book = [attributeDict valueForKey:@"name"];
		NSLog(@"Book: %@", theBible.book);
		return;
	}
	
	else if([elementName isEqualToString:@"chapter"]) 
	{
		theBible.chapterID =[attributeDict objectForKey:@"id"];
		NSLog(@"Chapter: %@", theBible.chapterID);
		return;
	}	
}


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

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
  namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
	if([elementName isEqualToString:@"bible"]){
			return;
	}	
	
}
 

- (void) dealloc {
	[theBible release];
	[currentElementValue release];
	[super dealloc];
}

@end
--------------------------------------------------------------------

The output I get in the debugger console:
2010-12-08 19:53:10.101 BibleXML[25641:207] found file and started parsing
2010-12-08 19:53:10.102 BibleXML[25641:207] Found element: bible
2010-12-08 19:53:10.103 BibleXML[25641:207] Testament: Old Testament
2010-12-08 19:53:10.103 BibleXML[25641:207] Book: Genesis
2010-12-08 19:53:10.104 BibleXML[25641:207] Chapter: Genesis 1
2010-12-08 19:53:10.104 BibleXML[25641:207] Chapter: Genesis 2
2010-12-08 19:53:10.105 BibleXML[25641:207] Book: Exodus
2010-12-08 19:53:10.105 BibleXML[25641:207] Chapter: Exodus 1
2010-12-08 19:53:10.106 BibleXML[25641:207] Chapter: Exodus 2
2010-12-08 19:53:10.107 BibleXML[25641:207] Testament: New Testament
2010-12-08 19:53:10.107 BibleXML[25641:207] Book: Matthew
2010-12-08 19:53:10.108 BibleXML[25641:207] Chapter: Matthew 1
2010-12-08 19:53:10.108 BibleXML[25641:207] Chapter: Matthew 2
2010-12-08 19:53:10.109 BibleXML[25641:207] Book: Revelation
2010-12-08 19:53:10.109 BibleXML[25641:207] Chapter: Revelation 1
2010-12-08 19:53:10.110 BibleXML[25641:207] Chapter: Revelation 2
2010-12-08 19:53:10.110 BibleXML[25641:207] No Errors
 
Last edited by a moderator:
I need help with parsing a xml file. My problem is I don't know how to implement the didEndElement delegate.
What I am trying to acheive is that I will have 2 cells where Old Testament and New Testament will be displayed and then the Books of the Bible and then the chapters.
If I can just get some help with the xml parsing the rest I can manage.
Seems to me to be a rather vague request. What help, specifically, are you needing?
 
Hi Dejo, I appreciate your help with this.
After parsing the XML, I need to put into an array to populate the UITableView. That's just where I'm running into problems. Any help would be appreciated.
Thanks!
 
Hi Dejo, I appreciate your help with this.
After parsing the XML, I need to put into an array to populate the UITableView. That's just where I'm running into problems. Any help would be appreciated.
Thanks!

What you have here is a called a SAX parser, or an event driven parser. The normal way to do this is to set boolean flags:

if startElement == "Old Testament"
boolean inOldTestament = true


if endElement == "Old Testment" && inOldTestament
Do something special do denote we are done with this old testament block
inOldTestament = false

This also means if you wanted to, you could handle multiple Old Testament blocks and be able to denote them differently. You would also rinse and repeat for each element that you wanted to keep track of.

In fact, you will be REQUIRED to do this if you want to read the data in between the <start> and </end> elements in the foundCharacters method. Otherwise you will have no idea of knowing which element you are in or what you want to append the found characters to.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.