Click here to Skip to main content
Click here to Skip to main content
Go to top

XML Parser for iPhone in Objective-C

, 21 Oct 2009
Rate this:
Please Sign up or sign in to vote.
An XML Parser for iPhone apps.

Using the code

This is an XML parser for iPhone apps. You can use the code in your iPhone XCode project by creating the class files and just passing the XML file to the static method of the parser class, and you get a filled XMLNode class structure which is like the root node of the standard XMLDocument class in many languages. For those of you used to C#, the style of doing this would be very familiar.

The XMLNode class has in it the name of the node and the value of the node. So for the following XML node line, in a file:

<NodeName>Node Value</NodeName>

the variable NSString nodeName would be NodeName, and NSString nodeValue would be "Node Value".

The XMLNode class stores XMLNode objects which are its children in the NSMutableArray childNodes variable. So you would iterate over all the children, accessing their node name and value information.

//
//  XMLNode.h
//
//  Created by Akshay Srinivasan on 7/17/09.
//  Copyright 2009 Epic Global Adventures. All rights reserved.
//

#import <foundation>


@interface XMLNode : NSObject {
    NSString *nodeName, *nodeValue;
    NSMutableArray *childNodes;
}

@property (retain, nonatomic) NSString *nodeName, *nodeValue;
@property (retain, nonatomic) NSMutableArray *childNodes;

- (id) init;
- (void) dealloc;
- (void) MyRelease;

@end

//
//  XMLNode.m
//
//  Created by Akshay Srinivasan on 7/17/09.
//  Copyright 2009 Epic Global Adventures. All rights reserved.
//

#import "XMLNode.h"


@implementation XMLNode

@synthesize nodeName, nodeValue, childNodes;

- (id) init
{
    if((self = [super init]))
    {
        self.childNodes = [NSMutableArray arrayWithCapacity: 1];
    }
    return self;
}

- (void) MyRelease
{
    for(int i=0; i < self.childNodes.count; i++)
    {
        [[self.childNodes objectAtIndex: i] MyRelease];
    }
    [self release];
}

- (void) dealloc
{
    if(self.nodeName != nil)
        [self.nodeName release];
    if(self.nodeValue != nil)
        [self.nodeValue release];
    [self.childNodes release];
    [super dealloc];
}

@end

The XMLParser class has two static methods, one of which is ParseFile, which expects you to pass it an NSData structure with the contents of the XML file you want parsed. The other method is not to be called (ParseString). The return value of the ParseFile method is just the root XMLNode instance in which is contained all the child nodes with the name/value pairs. You just iterate through this tree to access the XML data.

//
//  XMLParser.h
//  XMLTest
//
//  Created by Akshay Srinivasan on 7/17/09.
//  Copyright 2009 Epic Global Adventures. All rights reserved.
//

#import <foundation>
#import "XMLNode.h"


@interface XMLParser : NSObject {
    
}

+ (XMLNode *) ParseFile: (NSData *) data;
+ (int) ParseString: (NSString *) strData: (XMLNode *) parentNode: (int) pos;

@end


// XMLParser.m
//
// Created by Akshay Srinivasan on 7/17/09.
// Copyright 2009 Epic Global Adventures. All rights reserved.
//

#import "XMLParser.h"

@implementation XMLParser

NSString *strData, *strData2, *strData3;

+ (XMLNode *) ParseFile: (NSData *) data
{
    strData = [[NSString alloc] initWithData: data 
        encoding:NSASCIIStringEncoding];
    strData2 = [strData stringByReplacingOccurrencesOfString: @"\n" withString: @""];
    strData3 = [strData2 stringByReplacingOccurrencesOfString: @"\t" withString: @""];
    XMLNode *rootNode = [XMLNode new];
    [self ParseString: strData3: rootNode: 0];
    return rootNode;
}

+ (int) ParseString: (NSString *) strData: (XMLNode *) parentNode: (int) pos
{
    int i=pos;
    while (i < [strData length]) {
    NSRange l1;
    l1.location = i;
    l1.length = [strData length] - i;
    NSRange r1 = [strData rangeOfString: @"<" options: NSLiteralSearch range: l1];
    if(r1.length > 0)
    {
        i = r1.location + 1;
        l1.location = i;
        l1.length = [strData length] - i;
        NSRange r2 = [strData rangeOfString: @">" options: NSLiteralSearch range: l1];
        XMLNode *node1 = [XMLNode new];
        if(r2.length > 0)
        {
            i = r2.location + 1;
            NSRange nodeNameRange;
            nodeNameRange.location = r1.location + 1;
            nodeNameRange.length = r2.location - r1.location - 1;
            node1.nodeName = [[NSString alloc] initWithString: [strData 
                substringWithRange: nodeNameRange]];
            parentNode.childNodes addObject: node1];
            i = nodeNameRange.location + nodeNameRange.length + 1;
            NSString *nextChar = [strData substringWithRange: NSMakeRange(i, 1)];
            NSString *nextCharNot = [strData substringWithRange:
                NSMakeRange(i, 2)];
            int hasChildNodes = 0;
            while([nextChar isEqualToString: @"<"] == YES 
                && [nextCharNot isEqualToString: @"</"] != YES)
            {
                hasChildNodes = 1;
                i = [self ParseString:strData :node1 :i];
                if(i < [strData length])
                {
                    nextChar = [strData substringWithRange: NSMakeRange(i, 1)];
                    nextCharNot = [strData substringWithRange:
                        NSMakeRange(i, 2)];
                }
                else
                {
                    return [strData length];
                }
                NSString *endTag = [[NSString alloc] initWithFormat: 
                     @"</%s>", [node1.nodeName UTF8String]];
                NSRange rDataEnd = [strData rangeOfString: endTag
                     options: NSLiteralSearch range:
                     NSMakeRange(i, [strData length] - i)];
                if(hasChildNodes == 0)
                {
                    node1.nodeValue = [[NSString alloc] initWithString:
                         [strData substringWithRange:
                         NSMakeRange(i, rDataEnd.location - i)]];
                }
                return rDataEnd.location + rDataEnd.length;
           }
       }
       return [strData length];
}

@end

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Akshay Srinivasan2
Architect
India India
I have been coding since 1984 in a variety of languages. I originally started as a game programmer and then switched to business programming from 1990. I still program games.

Comments and Discussions

 
QuestionXML Parser for iPhone in Objective-C PinmemberAlainBouMalham6-Oct-11 0:20 
GeneralMy vote of 1 PinmemberKarstenK17-Sep-09 4:29 
GeneralMy vote of 1 PinmemberManas Bhardwaj17-Sep-09 3:17 
GeneralMy vote of 1 PinmvpDave Kreskowiak17-Sep-09 2:15 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140916.1 | Last Updated 22 Oct 2009
Article Copyright 2009 by Akshay Srinivasan2
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid