Translate

> > XML Parsing and Saving Using GDataXML

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


//
//  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


#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

use following function in any class where you want to build your parse method

#import "Party.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];
       
}

Download GDataXML class from here

Leave a Reply

Powered by Blogger.