XML Parsing and Saving Using GDataXML
Posted on Tuesday, October 25, 2011
|
No Comments
My XML Have Following pattern
<Party>
<Player>
<Name>Butch</Name>
<Level>1</Level>
<Class>Fighter</Class>
</Player>
<Player>
<Name>Shadow</Name>
<Level>2</Level>
<Class>Rogue</Class>
</Player>
<Player>
<Name>Crak</Name>
<Level>3</Level>
<Class>Wizard</Class>
</Player>
</Party>
So i have root node Party and a Child Node Player
After parsing XML i will be used two class for store data in memory. here is the two class
//Party.h
#import <Foundation/Foundation.h>
@interface Party : NSObject {
NSMutableArray *_players;
}
@property (nonatomic, retain) NSMutableArray *players;
@end
@interface Party : NSObject {
NSMutableArray *_players;
}
@property (nonatomic, retain) NSMutableArray *players;
@end
//
// Party.m
// XMLTest
//
// Created by Ray Wenderlich on 3/17/10.
// Copyright 2010 Ray Wenderlich. All rights reserved.
//
#import "Party.h"
@implementation Party
@synthesize players = _players;
- (id)init {
if ((self = [super init])) {
self.players = [[[NSMutableArray alloc] init] autorelease];
}
return self;
}
- (void) dealloc {
self.players = nil;
[super dealloc];
}
@end
// Party.m
// XMLTest
//
// Created by Ray Wenderlich on 3/17/10.
// Copyright 2010 Ray Wenderlich. All rights reserved.
//
#import "Party.h"
@implementation Party
@synthesize players = _players;
- (id)init {
if ((self = [super init])) {
self.players = [[[NSMutableArray alloc] init] autorelease];
}
return self;
}
- (void) dealloc {
self.players = nil;
[super dealloc];
}
@end
//
// Player.h
// XMLTest
//
// Created by Ray Wenderlich on 3/17/10.
// Copyright 2010 Ray Wenderlich. All rights reserved.
//
#import <Foundation/Foundation.h>
typedef enum {
RPGClassFighter,
RPGClassRogue,
RPGClassWizard
} RPGClass;
@interface Player : NSObject {
NSString *_name;
int _level;
RPGClass _rpgClass;
}
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) int level;
@property (nonatomic, assign) RPGClass rpgClass;
- (id)initWithName:(NSString *)name level:(int)level rpgClass:(RPGClass)rpgClass;
@end
// Player.h
// XMLTest
//
// Created by Ray Wenderlich on 3/17/10.
// Copyright 2010 Ray Wenderlich. All rights reserved.
//
#import <Foundation/Foundation.h>
typedef enum {
RPGClassFighter,
RPGClassRogue,
RPGClassWizard
} RPGClass;
@interface Player : NSObject {
NSString *_name;
int _level;
RPGClass _rpgClass;
}
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) int level;
@property (nonatomic, assign) RPGClass rpgClass;
- (id)initWithName:(NSString *)name level:(int)level rpgClass:(RPGClass)rpgClass;
@end
#import "Player.h"
@implementation Player
@synthesize name = _name;
@synthesize level = _level;
@synthesize rpgClass = _rpgClass;
- (id)initWithName:(NSString *)name level:(int)level rpgClass:(RPGClass)rpgClass {
if ((self = [super init])) {
self.name = name;
self.level = level;
self.rpgClass = rpgClass;
}
return self;
}
- (void) dealloc {
self.name = nil;
[super dealloc];
}
@end
@implementation Player
@synthesize name = _name;
@synthesize level = _level;
@synthesize rpgClass = _rpgClass;
- (id)initWithName:(NSString *)name level:(int)level rpgClass:(RPGClass)rpgClass {
if ((self = [super init])) {
self.name = name;
self.level = level;
self.rpgClass = rpgClass;
}
return self;
}
- (void) dealloc {
self.name = nil;
[super dealloc];
}
@end
use following function in any class where you want to build your parse method
#import "Party.h"
#import "Player.h"
#import "GDataXMLNode.h"
#import "Player.h"
#import "GDataXMLNode.h"
+ (Party *)loadParty {
NSString *filePath = [self dataFilePath:FALSE];
NSData *xmlData = [[NSMutableData alloc] initWithContentsOfFile:filePath];
NSError *error;
GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:xmlData options:0 error:&error];
if (doc == nil) { return nil; }
Party *party = [[[Party alloc] init] autorelease];
//NSArray *partyMembers = [doc.rootElement elementsForName:@"Player"];
NSArray *partyMembers = [doc nodesForXPath:@"//Party/Player" error:nil];
for (GDataXMLElement *partyMember in partyMembers) {
// Let's fill these in!
NSString *name;
int level;
RPGClass rpgClass;
// Name
NSArray *names = [partyMember elementsForName:@"Name"];
if (names.count > 0) {
GDataXMLElement *firstName = (GDataXMLElement *) [names objectAtIndex:0];
name = firstName.stringValue;
} else continue;
// Level
NSArray *levels = [partyMember elementsForName:@"Level"];
if (levels.count > 0) {
GDataXMLElement *firstLevel = (GDataXMLElement *) [levels objectAtIndex:0];
level = firstLevel.stringValue.intValue;
} else continue;
// Class
NSArray *classes = [partyMember elementsForName:@"Class"];
if (classes.count > 0) {
GDataXMLElement *firstClass = (GDataXMLElement *) [classes objectAtIndex:0];
if ([firstClass.stringValue caseInsensitiveCompare:@"Fighter"] == NSOrderedSame) {
rpgClass = RPGClassFighter;
} else if ([firstClass.stringValue caseInsensitiveCompare:@"Rogue"] == NSOrderedSame) {
rpgClass = RPGClassRogue;
} else if ([firstClass.stringValue caseInsensitiveCompare:@"Wizard"] == NSOrderedSame) {
rpgClass = RPGClassWizard;
} else {
continue;
}
} else continue;
Player *player = [[[Player alloc] initWithName:name level:level rpgClass:rpgClass] autorelease];
[party.players addObject:player];
}
[doc release];
[xmlData release];
return party;
}
+ (void)saveParty:(Party *)party {
GDataXMLElement * partyElement = [GDataXMLNode elementWithName:@"Party"];
for(Player *player in party.players) {
GDataXMLElement * playerElement = [GDataXMLNode elementWithName:@"Player"];
GDataXMLElement * nameElement = [GDataXMLNode elementWithName:@"Name" stringValue:player.name];
GDataXMLElement * levelElement = [GDataXMLNode elementWithName:@"Level" stringValue:[NSString stringWithFormat:@"%d", player.level]];
NSString *classString;
if (player.rpgClass == RPGClassFighter) {
classString = @"Fighter";
} else if (player.rpgClass == RPGClassRogue) {
classString = @"Rogue";
} else if (player.rpgClass == RPGClassWizard) {
classString = @"Wizard";
}
GDataXMLElement * classElement = [GDataXMLNode elementWithName:@"Class" stringValue:classString];
[playerElement addChild:nameElement];
[playerElement addChild:levelElement];
[playerElement addChild:classElement];
[partyElement addChild:playerElement];
}
GDataXMLDocument *document = [[[GDataXMLDocument alloc] initWithRootElement:partyElement] autorelease];
NSData *xmlData = document.XMLData;
NSString *filePath = [self dataFilePath:TRUE];
NSLog(@"Saving xml data to %@...", filePath);
[xmlData writeToFile:filePath atomically:YES];
}
NSString *filePath = [self dataFilePath:FALSE];
NSData *xmlData = [[NSMutableData alloc] initWithContentsOfFile:filePath];
NSError *error;
GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:xmlData options:0 error:&error];
if (doc == nil) { return nil; }
Party *party = [[[Party alloc] init] autorelease];
//NSArray *partyMembers = [doc.rootElement elementsForName:@"Player"];
NSArray *partyMembers = [doc nodesForXPath:@"//Party/Player" error:nil];
for (GDataXMLElement *partyMember in partyMembers) {
// Let's fill these in!
NSString *name;
int level;
RPGClass rpgClass;
// Name
NSArray *names = [partyMember elementsForName:@"Name"];
if (names.count > 0) {
GDataXMLElement *firstName = (GDataXMLElement *) [names objectAtIndex:0];
name = firstName.stringValue;
} else continue;
// Level
NSArray *levels = [partyMember elementsForName:@"Level"];
if (levels.count > 0) {
GDataXMLElement *firstLevel = (GDataXMLElement *) [levels objectAtIndex:0];
level = firstLevel.stringValue.intValue;
} else continue;
// Class
NSArray *classes = [partyMember elementsForName:@"Class"];
if (classes.count > 0) {
GDataXMLElement *firstClass = (GDataXMLElement *) [classes objectAtIndex:0];
if ([firstClass.stringValue caseInsensitiveCompare:@"Fighter"] == NSOrderedSame) {
rpgClass = RPGClassFighter;
} else if ([firstClass.stringValue caseInsensitiveCompare:@"Rogue"] == NSOrderedSame) {
rpgClass = RPGClassRogue;
} else if ([firstClass.stringValue caseInsensitiveCompare:@"Wizard"] == NSOrderedSame) {
rpgClass = RPGClassWizard;
} else {
continue;
}
} else continue;
Player *player = [[[Player alloc] initWithName:name level:level rpgClass:rpgClass] autorelease];
[party.players addObject:player];
}
[doc release];
[xmlData release];
return party;
}
+ (void)saveParty:(Party *)party {
GDataXMLElement * partyElement = [GDataXMLNode elementWithName:@"Party"];
for(Player *player in party.players) {
GDataXMLElement * playerElement = [GDataXMLNode elementWithName:@"Player"];
GDataXMLElement * nameElement = [GDataXMLNode elementWithName:@"Name" stringValue:player.name];
GDataXMLElement * levelElement = [GDataXMLNode elementWithName:@"Level" stringValue:[NSString stringWithFormat:@"%d", player.level]];
NSString *classString;
if (player.rpgClass == RPGClassFighter) {
classString = @"Fighter";
} else if (player.rpgClass == RPGClassRogue) {
classString = @"Rogue";
} else if (player.rpgClass == RPGClassWizard) {
classString = @"Wizard";
}
GDataXMLElement * classElement = [GDataXMLNode elementWithName:@"Class" stringValue:classString];
[playerElement addChild:nameElement];
[playerElement addChild:levelElement];
[playerElement addChild:classElement];
[partyElement addChild:playerElement];
}
GDataXMLDocument *document = [[[GDataXMLDocument alloc] initWithRootElement:partyElement] autorelease];
NSData *xmlData = document.XMLData;
NSString *filePath = [self dataFilePath:TRUE];
NSLog(@"Saving xml data to %@...", filePath);
[xmlData writeToFile:filePath atomically:YES];
}
Download GDataXML class from here