XML解析与创建(GDataXML)

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: 小  |  中  |  大  |  超大  

一、xml解析

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

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

<list>

<OrderData xmlns:name_space="http://www.baidu.com"xmlns="http://www.google.com/hk"attribute="party's attribute"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来打印):

+ (void)parseXMLDemo {

NSError*error =nil;

NSString*filePath0 = [[NSBundle mainBundle] pathForResource:@"Attribute"ofType:@"xml"];

NSData*xmldata0 =[[NSData alloc] initWithContentsOfFile:filePath0];

GDataXMLDocument*doc0 = [[GDataXMLDocument alloc] initWithData:xmldata0 options:0error:&error];

GDataXMLElement*rootElement =doc0.rootElement;if(error !=nil) {

NSLog(@"Attribute.xml parsed error!\n%@", [error localizedDescription]);return;

}

NSLog(@"%@", rootElement);

NSArray*messages = [rootElement elementsForName:@"OrderData"];if(messages.count >0) {for(GDataXMLElement *elementinmessages) {//取OrderData的HASH属性值NSLog(@"attrute:%@", [[element attributeForName:@"HASH"] stringValue]);//获取所有命名空间nameSpacesNSArray *nameSpaces = [element namespaces];//if(nameSpaces.count >0) {

[nameSpaces enumerateObjectsUsingBlock:^(GDataXMLNode *node, NSUInteger idx, BOOL *stop) {//获取所有命名空间的名字与值NSLog(@"|%@:%@|", [node name], [node stringValue]);

}];

}//取OrderData的HASH属性值,如果没有值,取出来的则是所有子值的组合(这里是:97cdbadaodd10odd11odd12l)NSLog(@"OrderData:%@", [element stringValue]);//获取id子元素数组NSArray *elementIDs = [element elementsForName:@"id"];if(elementIDs.count >0) {for(GDataXMLElement *eIDinelementIDs) {

NSLog(@"id:%d", [[eID stringValue] intValue]);//获取ID的值}

}//获取customer子元素数组NSArray *elementCustomers = [element elementsForName:@"customer"];if(elementCustomers.count >0) {for(GDataXMLElement *eIDinelementCustomers) {

NSArray*customerDatas = [eID elementsForName:@"CustomerData"];if(customerDatas.count >0) {for(GDataXMLElement *customerDataincustomerDatas) {

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 *eIDinelementBillingAddresses) {

NSLog(@"billingAddress:%@", [eID stringValue]);//获取billingAddress的值}

}//获取deliveryAddress子元素数组NSArray *elementDeliveryAddressses = [element elementsForName:@"deliveryAddress"];if(elementDeliveryAddressses.count >0) {for(GDataXMLElement *eIDinelementDeliveryAddressses) {

NSLog(@"deliveryAddress:%@", [eID stringValue]);//获取deliveryAddress的值}

}//获取orderDetail子元素数组NSArray *elementOrderDetails = [element elementsForName:@"orderDetail"];if(elementOrderDetails.count >0) {for(GDataXMLElement *eIDinelementOrderDetails) {

NSArray*lists = [eID elementsForName:@"list"];if(lists.count >0) {for(GDataXMLElement *listinlists) {

NSArray*OrderDetailDatas = [list elementsForName:@"OrderDetailData"];if(OrderDetailDatas.count >0) {for(GDataXMLElement *OrderDetailDatainOrderDetailDatas) {

NSLog(@"OrderDetailData-attribute:%@", [[OrderDetailData attributeForName:@"HASH"] stringValue]);

NSLog(@"OrderDetailData:%@", [OrderDetailData stringValue]);

}

}

}

}

}

}//获取log子元素数组NSArray *elementLogs = [element elementsForName:@"log"];if(elementLogs.count >0) {for(GDataXMLElement *eIDinelementLogs) {

NSLog(@"log:%@", [eID stringValue]);//获取log的值}

}

}

}

}

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

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

二、XML创建

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

<Party xmlns:name space="http://www.baidu.com"xmlns="http://www.google.com/hk"attribute="party's attribute">

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

RPGClassFighter=0,

RPGClassRogue,

RPGClassWizard

} RPGClass;@interfacePlayer : NSObject

@PRoperty (copy, nonatomic) NSString*name;

@propertyintlevel;

@property RPGClass rpgClass;- (id)initWithName:(NSString *)aName level:(int)aLevel rpgClass:(RPGClass)aRPGClass;@end//Player.m文件#import"Player.h"@implementationPlayer- (id)initWithName:(NSString *)aName level:(int)aLevel rpgClass:(RPGClass)aRPGClass {if(self =[super init]) {

_name=aName;

_level=aLevel;

_rpgClass=aRPGClass;

}returnself;

}@end//Party.h文件#import<Foundation/Foundation.h>@interfaceParty : NSObject

@property (strong, nonatomic) NSMutableArray*players;@end//Party.m#import"Party.h"#import"Player.h"@implementationParty-(instancetype)init

{

self=[super init];if(self) {

_players=[[NSMutableArray alloc] init];

}returnself;

}@end

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

+ (void)saveParty:(Party *)aParty {

GDataXMLElement*partyElement = [GDataXMLElement elementWithName:@"Party"];//添加属性[partyElement addAttribute:[GDataXMLNode elementWithName:@"attribute"stringValue:@"party's attribute"]];//添加命名空间[partyElement addNamespace:[GDataXMLNode namespaceWithName:@"name space"stringValue:@"http://www.baidu.com"]];//添加缺省命名空间[partyElement addNamespace:[GDataXMLNode namespaceWithName:@""stringValue:@"http://www.google.com/hk"]];for(Player *playerinaParty.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*rpgClass =nil;if(player.rpgClass ==RPGClassFighter) {

rpgClass=@"Fighter";

}elseif(player.rpgClass ==RPGClassRogue) {

rpgClass=@"Rogue";

}elseif(player.rpgClass ==RPGClassWizard) {

rpgClass=@"Wizard";

}

GDataXMLElement*rpgClassElement = [GDataXMLNode 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 =[doc XMLData];

NSString*filePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"makeXMLFile.xml"];

[xmlData writeToFile:filePath atomically:YES];

}

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

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航