Parsing XML file - Please help!!

Discussion in 'iOS Programming' started by tssav, Dec 8, 2010.

  1. tssav, Dec 8, 2010
    Last edited by a moderator: Dec 8, 2010

    tssav macrumors newbie

    Dec 8, 2010
    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:
    <?xml version="1.0" encoding="UTF-8"?>
    	<testament name="Old Testament">
    		<book name="Genesis">
    			<chapter id="Genesis 1"></chapter>
    			<chapter id="Genesis 2"></chapter>
    		<book name="Exodus">
    			<chapter id="Exodus 1"></chapter>
    			<chapter id="Exodus 2"></chapter>
    	<testament name="New Testament">
    		<book name="Matthew">
    			<chapter id="Matthew 1"></chapter>
    			<chapter id="Matthew 2"></chapter>
    		<book name="Revelation">
    			<chapter id="Revelation 1"></chapter>
    			<chapter id="Revelation 2"></chapter>
    //  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;
    //  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];
    //  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;
    //  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); = [[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);
    	else if ([elementName isEqualToString:@"book"])
    	{ = [attributeDict valueForKey:@"name"];
    		NSLog(@"Book: %@",;
    	else if([elementName isEqualToString:@"chapter"]) 
    		theBible.chapterID =[attributeDict objectForKey:@"id"];
    		NSLog(@"Chapter: %@", theBible.chapterID);
    - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
      namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    	if([elementName isEqualToString:@"bible"]){
    - (void) dealloc {
    	[theBible release];
    	[currentElementValue release];
    	[super dealloc];

    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
  2. dejo Moderator


    Staff Member

    Sep 2, 2004
    The Centennial State
    Seems to me to be a rather vague request. What help, specifically, are you needing?
  3. tssav thread starter macrumors newbie

    Dec 8, 2010
    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.
  4. ulbador macrumors 68000


    Feb 11, 2010
    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.
  5. dejo Moderator


    Staff Member

    Sep 2, 2004
    The Centennial State
    An array of what? That is, what datatype will each element of the array be?

Share This Page