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 = [doc XMLData];
    NSString *filePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"makeXMLFile.xml"];
    [xmlData writeToFile:filePath atomically:YES];
}

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

时间: 2024-10-10 23:15:15

XML解析与创建(GDataXML)的相关文章

UI进阶 XML解析适配 引入GDataXML文件时候 &#39;libxml/tree.h&#39;file not found 错误解决办法

在工程的"Build Settings"页中找到"Header Search Path"项,添加"/usr/include/libxml2". 在"Other Linker Flags"项,添加"-lxml2" 同理引入别的类型文件不匹配的时候也可以用这种方法 UI进阶 XML解析适配 引入GDataXML文件时候 'libxml/tree.h'file not found 错误解决办法

iOS网络数据解析之XML解析-GDataXML

GDataXML 第三方xml解析框架 DOM解析:一次性将整个XML文档加载进内存,比较适合解析小文件 GDataXML中常用的类 GDataXMLDocument: 代表整个XML文档 GDataXMLElement: 代表文档中的每个元素 使用attributeForName:方法可以获得属性值 要使用GDataXML,先要对项目进行一些配置.1>导入libxml2动态库targets--Build Phases--link Binary With Libraries 2>设置libxm

XML文件的创建和解析笔记

解析XML的四种方法 XML现在已经成为一种通用的数据交换格式,它的平台无关性,语言无关性,系统无关性,给数据集成与交互带来了极大的方便.对于XML本身的语法知识与技术细节,需要阅读相关的技术文献,这里面包括的内容有DOM(Document Object Model),DTD(Document Type Definition),SAX(Simple API for XML),XSD(Xml Schema Definition),XSLT(Extensible Stylesheet Languag

Android中解析与创建XML文件

Android中解析与创建XML文件 在Android中对XML的操作有多种方式,常见的有三种方式:SAX.DOM和PULL方式. DOM方式会把整个XML文件加载到内存中,在PC上常使用DOM的方式. 但是在性能敏感的设备上,主要采用的是SAX的方式,但是缺点是嵌套多个分支的时候处理不是很方便. 而PULL的方式类似SAX方式,同样很节省内存. 因此,本文章中只提供PULL的方式解析与创建XML文件. 基础类 本例中使用的实体类的定义如下: public class CAddress impl

XML解析

3.1 XML简单介绍 (1) XML:可扩展标记语言 a.语法 b.XML文档的三部分(声明.元素和属性) c.其它注意点(注意不能交叉包含.空行换行.XML文档只能有一个根元素等) (2) XML解析 a.XML解析的两种方式 001 SAX:从根元素开始,按顺序一个元素一个元素的往下解析,可用于解析大.小文件 002 DOM:一次性将整个XML文档加载到内存中,适合较小的文件 b.解析XML的工具 001 苹果原生NSXMLParser:使用SAX方式解析,使用简单 002 第三方框架 l

Json和XML解析

NSXMLParse 关于XML,有两种解析方式,分别是SAX(Simple API for XML,基于事件驱动的解析方式,逐行解析数据,采用协议回调机制)和DOM(Document Object Model ,文档对象模型.解析时需要将XML文件整体读入,并且将XML结构化成树状,使用时再通过树状结构读取相关数据,查找特定节点,然后对节点进行读或写).苹果官方原生的NSXMLParse类库采用第一种方式,即SAX方式解析XML,它基于事件通知的模式,一边读取文档一边解析数据,不用等待文档全部

iOS - - JSON 和 XML解析

JSON 和 XML 一.JSON 1.什么是JSON JSON是一种轻量级的数据格式,一般用于数据交互 服务器返回给客户端的数据,一般都是JSON格式或者XML格式(文件下载除外) 2.JSON的格式很像OC中的字典和数组 {"name" : "jack", "age" : 10} {"names" : ["jack", "rose", "jim"]} 标准JSON

iOS网络编程开发—JSON解析与XML解析

一.什么是JSON JSON是一种轻量级的数据格式,一般用于数据交互 服务器返回给客户端的数据,一般都是JSON格式或者XML格式(文件下载除外) JSON的格式很像OC中的字典和数组 {"name" : "jack", "age" : 10} {"names" : ["jack", "rose", "jim"]} 标准JSON格式的注意点:key必须用双引号 要想从

iOS xml解析

iOS xml 解析方法有两种:SAX , DOM. SAX 不用借助第三方,在解析过程中逐行解析.(NSXMLParser,需要实现代理),具体步骤: 1.获取文件路径. 2.创建 NSXMLParser 对象. 3.遵守协议,设置代理. 4.实现代理方法 1>- (void)parserDidStartDocument:  ---- 开始解析 2>- (void)parserDidEndDocument: ----解析结束 3>- (void)parser:didStartEleme