首页 > 代码库 > XML解析与创建(GDataXML)

XML解析与创建(GDataXML)

 一、XML解析

  对于JSON解析,iOS5之前有比较多的开源三方类(如JSONKit等)支持,一行代码搞定;iOS5后JSON可以用原生API解析,不仅方便而且高效。但是XML解析原生的API不是很友好,解析也麻烦;还好可以用Google的GDataXML来解析,怎么集成GDataXML到工程请查看我以前的随笔,用GDataXML稍稍好解析一点,XML的解析原理可以理解成:脱衣模式,想要洗澡就要把衣服从外到里依次脱掉,然后每件衣服都可以看做是一个GDataElement,每一个GDataElement都有自己的值与属性,下面来解析以下XML数据。

XML文件数据(文件名位Attribute.xml):

<list>    <OrderData HASH="1408108039">od0</OrderData>    <OrderData HASH="208524692">        <id>97</id>        <customer>            <CustomerData HASH="2128670187">cd</CustomerData>        </customer>        <billingAddress>ba</billingAddress>        <deliveryAddress>da</deliveryAddress>        <orderDetail>            <list>                <OrderDetailData HASH="516790072">odd10</OrderDetailData>                <OrderDetailData HASH="11226247">odd11</OrderDetailData>                <OrderDetailData HASH="11226247">odd12</OrderDetailData>            </list>        </orderDetail>        <log>l</log>    </OrderData>    <OrderData HASH="1502226778">odd20</OrderData></list>

OC解析代码(所有element的值与属性用log来打印):

    NSError *error = nil;    NSString *filePath0 = [[NSBundle mainBundle] pathForResource:@"Attribute" ofType:@"xml"];// 获取工程内Attribute.xml文件    NSData *xmldata0 = [[NSData alloc] initWithContentsOfFile:filePath0];    GDataXMLDocument *doc0 = [[GDataXMLDocument alloc] initWithData:xmldata0 options:0 error:&error];    GDataXMLElement *rootElement = doc0.rootElement;//获取跟节点    NSLog(@"%@", rootElement);    NSArray *messages = [rootElement elementsForName:@"OrderData"];    if (messages.count > 0) {        for (GDataXMLElement *element in messages) {            //取OrderData的HASH属性值            NSLog(@"attrute:%@", [[element attributeForName:@"HASH"] stringValue]);            //取OrderData的HASH属性值,如果没有值,取出来的则是所有子值的组合(这里是:97cdbadaodd10odd11odd12l)            NSLog(@"OrderData:%@", [element stringValue]);            //获取id子元素数组            NSArray *elementIDs = [element elementsForName:@"id"];            if (elementIDs.count > 0) {                for (GDataXMLElement *eID in elementIDs) {                    NSLog(@"id:%d", [[eID stringValue] intValue]);  // 获取ID的值                }            }                        //获取customer子元素数组            NSArray *elementCustomers = [element elementsForName:@"customer"];            if (elementCustomers.count > 0) {                for (GDataXMLElement *eID in elementCustomers) {                    NSArray *customerDatas = [eID elementsForName:@"CustomerData"];                    if (customerDatas.count > 0) {                        for (GDataXMLElement *customerData in customerDatas) {                            NSLog(@"customerData:%@", [customerData stringValue]);  // 获取customerData的值                            NSLog(@"customerData-attrute:%@", [[customerData attributeForName:@"HASH"] stringValue]);  // 获取customerData的HASH属性值                        }                    }                }            }                      //获取billingAddress子元素数组            NSArray *elementBillingAddresses = [element elementsForName:@"billingAddress"];            if (elementBillingAddresses.count > 0) {                for (GDataXMLElement *eID in elementBillingAddresses) {                    NSLog(@"billingAddress:%@", [eID stringValue]);  // 获取billingAddress的值                }            }                        //获取deliveryAddress子元素数组            NSArray *elementDeliveryAddressses = [element elementsForName:@"deliveryAddress"];            if (elementDeliveryAddressses.count > 0) {                for (GDataXMLElement *eID in elementDeliveryAddressses) {                    NSLog(@"deliveryAddress:%@", [eID stringValue]);// 获取deliveryAddress的值                }            }            //获取orderDetail子元素数组            NSArray *elementOrderDetails = [element elementsForName:@"orderDetail"];            if (elementOrderDetails.count > 0) {                for (GDataXMLElement *eID in elementOrderDetails) {                    NSArray *lists = [eID elementsForName:@"list"];                    if (lists.count > 0) {                        for (GDataXMLElement *list in lists) {                            NSArray *OrderDetailDatas = [list elementsForName:@"OrderDetailData"];                            if (OrderDetailDatas.count > 0) {                                for (GDataXMLElement *OrderDetailData in OrderDetailDatas) {                                    NSLog(@"OrderDetailData-attribute:%@", [[OrderDetailData attributeForName:@"HASH"] stringValue]);                                    NSLog(@"OrderDetailData:%@", [OrderDetailData stringValue]);                                }                            }                        }                    }                }            }            //获取log子元素数组            NSArray *elementLogs = [element elementsForName:@"log"];            if (elementLogs.count > 0) {                for (GDataXMLElement *eID in elementLogs) {                    NSLog(@"log:%@", [eID stringValue]);// 获取log的值                }            }        }    }

这样一层一层的解析是不是很清楚,妈妈在也不用担心我解不了复杂的XML了。在这里分享一个小技巧,获取节点的时候不用这样获取节点:GDataXMLElement *rootElement = doc.rootElement;

可以通过路径直接获取相应的节点:NSArray *nodes = [doc nodesForXPath:@"//Party/Player" error:&error];,这样做得好处是在一个比较复杂的XML文件中不用一层一层的遍历,直接取到直接想要的那层。

 

二、XML创建

XML创建与解析是一个逆过程,可以理解为:穿衣模式,冬天起床,创衣服的顺序依次是穿里衣,毛衣,外套等。创建XML文件也是一样,先创建添加最里层元素(GDataXMLElement),那么下面我们来创建有以下数据的xml文件

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

为了在简化创建的代码与逻辑,我们先创建Player与Party两个OC类

//  Player.h文件#import <Foundation/Foundation.h>typedef enum {    RPGClassFighter = 0,    RPGClassRogue,    RPGClassWizard} RPGClass;@interface Player : NSObject@property (copy, nonatomic) NSString *name;@property int level;@property RPGClass rpgClass;- (id)initWithName:(NSString *)aName level:(int)aLevel rpgClass:(RPGClass)aRPGClass;@end//  Player.m文件#import "Player.h" @implementation Player- (id)initWithName:(NSString *)aName level:(int)aLevel rpgClass:(RPGClass)aRPGClass {    if (self = [super init]) {        _name = aName;        _level = aLevel;        _rpgClass = aRPGClass;    }    return self;}@end//  Party.h文件#import <Foundation/Foundation.h>@interface Party : NSObject@property (strong, nonatomic) NSMutableArray *players;@end//  Party.m#import "Party.h"#import "Player.h"@implementation Party- (instancetype)init{    self = [super init];    if (self) {        _players = [[NSMutableArray alloc] init];    }    return self;}@end

创建XML方法(创建三个Player这里没有给出,请读者直接写一下哈)

+ (void)saveParty:(Party *)aParty {    GDataXMLElement *partyElement = [GDataXMLElement elementWithName:@"Party"];    [partyElement addAttribute:[GDataXMLElement elementWithName:@"attribute" stringValue:@"party‘s attribute"]];    for (Player *player in aParty.players) {        GDataXMLElement *playerElement = [GDataXMLElement elementWithName:@"Player"];   // 创建元素        GDataXMLElement *nameElement = [GDataXMLElement elementWithName:@"Name" stringValue:player.name];        GDataXMLElement *levelElement = [GDataXMLElement elementWithName:@"Level" stringValue:[NSString stringWithFormat:@"%d", player.level]];        NSString *rpgClass = nil;        if (player.rpgClass == RPGClassFighter) {            rpgClass = @"Fighter";        } else if (player.rpgClass == RPGClassRogue) {            rpgClass = @"Rogue";        }else if (player.rpgClass == RPGClassWizard) {            rpgClass = @"Wizard";        }        GDataXMLElement *rpgClassElement = [GDataXMLElement elementWithName:@"Class" stringValue:rpgClass];        [playerElement addChild:nameElement];       // 给player添加name元素        [playerElement addChild:levelElement];      // 给player添加level元素        [playerElement addChild:rpgClassElement];   // 给player添加rpgClass元素        [partyElement addChild:playerElement];      // 给party添加player元素    }    GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithRootElement:partyElement];    NSData *xmlData = http://www.mamicode.com/[doc XMLData];"makeXMLFile.xml"];    [xmlData writeToFile:filePath atomically:YES];}

看完代码是不是觉得XML创建也不难吧(如有不合理地方请指正,谢谢!)

XML解析与创建(GDataXML)