[置顶] IOS开发中使用GDataXmlNode解析xml

       xml的解析在ios网络开发的时候非常常见,不同的xml的树形的结构各不相同,这篇文中介绍根据不同的xml的结构解析出xml,保存到字典中,如果解析的数据将会多次用到,建议建立数据实体,不然在多个场景中都必须知道字典中的键值,用起来非常不方便。

      我最近开发的项目中用到xml解析,我用到一个工厂模式来建立一个解析的方式。

1:下载GDataXmlNode.h 和GDataXmlNode.m,并添加到项目中,具体的使用和和配置方法在GDataXmlNode.h 的注释中有,这步就不分解了,在不行就google下

2:   我在这个过程中用到6个文件,BaseParser.h,BaseParser.m,DataParser.h和DataParser.m ,LoginParser.h,LoginParser.m,其中BaseParser用于定义和实现基类的方法,LoginParser继承于BaserParser,实现了父类中申明的解析xml文件和组装xml文件的方法。DataParser中根据不同的xml类型来实例化解析类,这里就是LoginParser(也就是说,还可以实例化任意多个BaseParser的子类).

3,GDataxmlNode 的使用在LoginParser中很能得以体现总的思路就是  字典,字符串,GDataxmlDocumet 这个类型的实例之间相互转化,以完成xml的组装和解析。

BaseParser.h

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

@interface BaseParser : NSObject
{
    NSString                                      *xmlContent;        //字符串形式的xml内容
    NSMutableDictionary            *parsedContent; //对应的字典
}

@property(nonatomic,retain)NSString *xmlContent;

- (id)initWithXmlString:(NSString *)xmlString;
- (NSDictionary *)getCurrentList;
- (id)initWithUserDicionary:(NSDictionary*)dicionary;
- (id)getCurrentData;
@end

BaseParser.m

#import "BaseParser.h"
@implementation Baseparser
@synthesize xmlContent;
-(id)init
{
    self = [super init];
    if (self) {
        parsedContent = [[NSMutableDictionary alloc]init];
        xmlContent    = [[NSString alloc]init];
    }
    return self;
}
-(void)dealloc
{
    [parsedContent release];
    [xmlContent release];
    [super dealloc];
    
}
- (id)initWithXmlString:(NSString *)xmlString
{
    return nil;
}
- (id)initWithUserDicionary:(NSDictionary *)dicionary
{
    return nil;
}

- (NSDictionary *)getCurrentList
{
	return [NSDictionary dictionaryWithDictionary:parsedContent]; 
}
- (id)getCurrentData
{
    return [NSString stringWithString:xmlContent];
}

LoginParser.h

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

@interface LoginParser : BaseParser

@end

LoginParser.m

#import "LoginParser.h"

@implementation LoginParser
- (void)dealloc
{
    [super dealloc];
}
- (id)initWithXmlString:(NSString *)xmlString
{
    self = [super init];
    if (self) {
        NSError *error;
        GDataXMLDocument *dataDocument = [[GDataXMLDocument alloc]initWithXMLString:xmlString options:0 error:&error ];
        GDataXMLElement *root = [dataDocument rootElement];
        NSArray *array = [NSArray arrayWithObjects:@"code",@"desc",@"sessionId",@"user_id",@"name", nil];
        for (int index = 0; index<[array count]; index++) {
            GDataXMLElement *element = [[root elementsForName:[array objectAtIndex:index]]lastObject];
            NSString *aValue = (NSString*)[element stringValue];
            if (aValue) {
                [parsedContent  setObject:aValue forKey:[array objectAtIndex:index]];
            }
        }
        [dataDocument release];
        
    }
	return self;
}
- (id)initWithUserDicionary:(NSDictionary *)dicionary
{
    self = [self init];
    if (self) {
        [dicionary retain];
        GDataXMLElement *rootElement = [GDataXMLElement elementWithName:@"root"];
        NSArray *elementArray = [NSArray arrayWithObjects:@"name",@"type",@"password", nil];
        for (int index = 0; index<[elementArray count]; index++) {
            GDataXMLElement *element = [GDataXMLElement elementWithName:[elementArray objectAtIndex:index] stringValue:[dicionary objectForKey:[elementArray objectAtIndex:index]]];
            [rootElement addChild:element];
        }
        [dicionary release];
        GDataXMLDocument *xmlDocument = [[GDataXMLDocument alloc]initWithRootElement:rootElement];
        NSString *xmlString = [[NSString alloc]initWithData:xmlDocument.XMLData encoding:NSUTF8StringEncoding];
        xmlContent = @"";
        xmlContent = [xmlContent stringByAppendingString:xmlString];
        [xmlString release];
        [xmlDocument release];
        
    }
    
    return self;
}


DataParser.h

#import <Foundation/Foundation.h>

@interface DataParser : NSObject


+ (id)CreateParserObjectWithData:(id)xmlString andTypeIs:(NSInteger)aType;     // 根据不同的类型用字典组装成xml
+ (id)CreateDeparserObjectWithData:(id)xmlString andTypeIs:(NSInteger)aType;//将xml解析成字典
@end


DataParser.m

#import "LoginParser.h"
@implementation DataParser
//这俩个简单的工厂来组装和解析xml 
+ (id)CreateParserObjectWithData:(id)xmlString andTypeIs:(NSInteger)aType
{
    switch (aType) {
        case LOGINSERVICETYPE :
        {
            LoginParser *parser  = [[BCLogin alloc]initWithXmlString:xmlString];
            NSDictionary *dictionary = [urlList getCurrentList];
            [ parser release];
            return dictionary ;
        }
            break;
}
+ (id)CreateDeparserObjectWithData:(id)xmlString andTypeIs:(NSInteger)aType
{
    
    switch (aType) {
        case LOGINSERVICETYPE :
        {
            LoginParser *parser = [[BCLogin alloc]initWithUserDicionary:xmlString];
            NSData  *data    = [urlList getCurrentData];
            [parser release];
            return data ;
        }
            break;
}

4:使用

新建一个文件LoginViewController,在程序束中加入 LoginReturn.xml,

LoginViewController.m

#define    LOGINSERVICETYPE  100
#import "LoginViewController.h"

@implementation LoginViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)didReceiveMemoryWarning
{
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
    
    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
   //使用解析的工厂,组装xml就不写了
    NSString *string =  NSError *error;
    NSString *xmlString = [NSString stringWithContentsOfFile:[[[NSBundle mainBundle]bundlePath]stringByAppendingPathComponent:@"LoginReturn.xml"] 
     encoding:NSUTF8StringEncoding error:&error];
     NSMutableDictionary *dic =    [NSMutableDictionary dictionaryWithDictionary:
                                                                   [BCBaseParser CreateParserObjectWithData:xmlString andTypeIs:self.parserType]]
   //这里获得的dic就是包含了sessionId,userId,等键的字典
 }

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

@end

 不好把我在项目中的代码貼出来,我是在post不同的xml中用到这个方式

转载请注明出处


总结:

        代码的重用非常重要,在开发过程中尽量遵守一般的开发原则,比如OCP,这篇文中较好的体现了这一原则,同时GDataXmlNode避免了官方的类回调的使用,十分方便,推荐使用。

你可能感兴趣的:(xml,Google,interface,Dictionary,encoding,initialization)