NSXMLParse

关于XML,有两种解析方式,分别是SAX(Simple API for XML,基于事件驱动的解析方式,逐行解析数据,采用协议回调机制)和DOM(Document Object Model ,文档对象模型。解析时需要将XML文件整体读入,并且将XML结构化成树状,使用时再通过树状结构读取相关数据,查找特定节点,然后对节点进行读或写)。苹果官方原生的NSXMLParse类库采用第一种方式,即SAX方式解析XML,它基于事件通知的模式,一边读取文档一边解析数据,不用等待文档全部读入以后再解析,所以如果你正打印解析的数据,而解析过程中间出现了错误,那么在错误节点之间的数据会正常打印,错误后面的数据不会被打印。解析过程由NSXMLParserDelegate协议方法回调。

插句题外话先,我在写这种方式解析XML数据的Demo时折腾了整整一天,说起来都有些不好意思了。程序运行的时候一直出现不能完成解析的情况,各种查各种试,真的是整了整整一天的时间。就在崩溃的边缘的时候,我竟然发现在我自己写XML文件时少写了一个“/。。。瞬间感觉整个世界都崩塌了。所以特地记下来警示自己也顺便给大家提个醒,在这种低级失误上浪费整整一天的时间,要多不值有多不值。谨记,谨记。

我们遵循MVC,首先我们创建模型,新建一个person类,存放XML文件中描述的person属性。再来一个解析XML文件的工具类XMLUtil,我们在里面实现文件的获取,代理方法的实现。

先来看这两个类的代码:

//person.h

#import <Foundation/Foundation.h>

@interface person : NSObject
@property (nonatomic, copy) NSString *pid;
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *sex;
@property (nonatomic, copy) NSString *age;
@end
//XMLUtil.h

#import <Foundation/Foundation.h>
#import "person.h"
//声明代理
@interface XMLUtil : NSObject<NSXMLParserDelegate>
//添加属性
@property (nonatomic, strong) NSXMLParser *par;
@property (nonatomic, strong) person *person;
//存放每个person
@property (nonatomic, strong) NSMutableArray *list;
//标记当前标签,以索引找到XML文件内容
@property (nonatomic, copy) NSString *currentElement; //声明parse方法,通过它实现解析
-(void)parse;
@end //XMLUtil.m #import "XMLUtil.h" @implementation XMLUtil - (instancetype)init{
self = [super init];
if (self) {
//获取事先准备好的XML文件
NSBundle *b = [NSBundle mainBundle];
NSString *path = [b pathForResource:@"test" ofType:@".xml"];
NSData *data = [NSData dataWithContentsOfFile:path];
self.par = [[NSXMLParser alloc]initWithData:data];
//添加代理
self.par.delegate = self;
//初始化数组,存放解析后的数据
self.list = [NSMutableArray arrayWithCapacity:5];
}
return self;
} //几个代理方法的实现,是按逻辑上的顺序排列的,但实际调用过程中中间三个可能因为循环等问题乱掉顺序
//开始解析
- (void)parserDidStartDocument:(NSXMLParser *)parser{
NSLog(@"parserDidStartDocument...");
}
//准备节点
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(nullable NSString *)namespaceURI qualifiedName:(nullable NSString *)qName attributes:(NSDictionary<NSString *, NSString *> *)attributeDict{ self.currentElement = elementName; if ([self.currentElement isEqualToString:@"student"]){
self.person = [[person alloc]init]; } }
//获取节点内容
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{ if ([self.currentElement isEqualToString:@"pid"]) { [self.person setPid:string];
}else if ([self.currentElement isEqualToString:@"name"]){
[self.person setName:string];
}else if ([self.currentElement isEqualToString:@"sex"]){
[self.person setSex:string];
}else if ([self.currentElement isEqualToString:@"age"]){ [self.person setAge:string];
}
} //解析完一个节点
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(nullable NSString *)namespaceURI qualifiedName:(nullable NSString *)qName{ if ([elementName isEqualToString:@"student"]) {
[self.list addObject:self.person];
}
self.currentElement = nil;
} //解析结束
- (void)parserDidEndDocument:(NSXMLParser *)parser{
NSLog(@"parserDidEndDocument...");
} //外部调用接口
-(void)parse{
[self.par parse]; } @end

OK,总算是大功告成,如果对代理的使用比较熟悉的话,这部分内容其实还蛮简单的。如果被代码转来转去弄晕了的话可以在每个block的最后都加一个打印输出,做好标记,你就能弄懂程序的执行顺序了。

我们点击NSXMLParse,有了!

GDataXML

来看GDataXML,它是一种DOM方式的解析类库。DOM实现的原理是把整个xml文档一次性读出,放在一个树型结构里。在需要的时候,查找特定节点,然后对节点进行读或写。

在使用之前呢,我们还是先从网上下载GDataXML包,里面两个文件GDataXMLNode.h和GDataXMLNode.m导入到项目中来,编译,发现报错了,这是因为GDataXML是依赖libmxl2的,我们要去项目的Target中做一些设置。

  • 找到项目的Tarfet,进入Build Phases里面的Link Binary With Libraries,点击“加号”,搜索libxml,把出现的包添加进去,这里最新版的XCode7和iOS9中,是libxml.2.2.tbd。
  • 再来到Build Settings,我们可以搜索一下,找到Header Search Paths,添加路径“/usr/include/libxml2”。
  • 再找到Other Link Flags,添加“-libxml2“
  • 还有就是如果你下载的GDataXML是不支持ARC的,那么你就要像上面那样去添加“-fno-objc-arc”,这个视你下载的GDataXML包版本而定。

再次编译,就顺利通过了。

接下来看看我们怎么用这个东西。贴代码之前我真的想说一句,比起苹果原生的类库,这些开源的第三方类库真的在用起来的时候不知道有多舒服,懒人必备啊。在实际的开发中可以为我们节省很多的时间与精力,但是还是要搞懂人家原生的东西,这样才叫学会了么。

//ViewController.m

- (IBAction)GDataXML:(id)sender {

    NSString *path = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"xml"];
NSData *data = [[NSData alloc]initWithContentsOfFile:path];
//对象初始化
GDataXMLDocument *doc = [[GDataXMLDocument alloc]initWithData:data error:nil];
//获取根节点
GDataXMLElement *rootElement = [doc rootElement];
//获取其他节点
NSArray *students = [rootElement elementsForName:@"student"];
//初始化可变数组,用来显示到textView
self.GDatatext = [[NSMutableString alloc]initWithString:@""];
for (GDataXMLElement *student in students) {
//获取节点属性
GDataXMLElement *pidElement = [[student elementsForName:@"pid"] objectAtIndex:0];
NSString *pid = [pidElement stringValue]; GDataXMLElement *nameElement = [[student elementsForName:@"name"] objectAtIndex:0];
NSString *name = [nameElement stringValue]; GDataXMLElement *sexElement = [[student elementsForName:@"sex"] objectAtIndex:0];
NSString *sex = [sexElement stringValue]; GDataXMLElement *ageElement = [[student elementsForName:@"age"] objectAtIndex:0];
NSString *age = [ageElement stringValue]; //调整一下姿势,添加到可变长字符串~~
NSString *t = [NSString stringWithFormat:@"学号:%@ 姓名:%@ 性别:%@ 年龄:%@\n", pid, name, sex, age];
[self.GDatatext appendString:t];
}
self.textView.text = self.GDatatext;
}

就一段,是不是看起来非常的舒服呢!

跑一下,跟我们刚才使用的NSXMLParse是不是一样呢?

 

哈,搞定!

XML解析总结

上述两种解析用到的类库分别代表了两种典型的XML数据解析方式,SAX和DOM,各有优势,比如在应对比较大数据量的XML文件时,后者由于需要先读取整个文档,性能和速度上就必然不及前者了。

其实现在在实际应用中XML已经越来越少了,但是说起iOS中的网络编程,就免不了和XML格式的数据打交道。还有就是,我们在这里仅仅介绍了两种常用的XML解析方式,如同解析Json数据一样,解析XML文件也有很多种方法,除了上述两种,还有比如像TBXML, TouchXML, KissXML, TinyXML等等,具体的使用方法可以去Github上找,都有使用方法的说明的。

文/神兽gcc(简书作者)
原文链接:http://www.jianshu.com/p/a54d367adb2a
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

Json和XML解析的更多相关文章

  1. 【.Net 】Json和Xml解析

    引言    Json和Xml是现在跨平台传输数据的主流格式,关于它们的解析,网上资料很多,我稍作整理,写成一个小demo,方便日后使用. JSON解析     能进行json解析的类库有很多,例如Ja ...

  2. iOS - - JSON 和 XML解析

    JSON 和 XML 一.JSON 1.什么是JSON JSON是一种轻量级的数据格式,一般用于数据交互 服务器返回给客户端的数据,一般都是JSON格式或者XML格式(文件下载除外) 2.JSON的格 ...

  3. 网络HTTP、JSON、XML解析等 复习

    一.一个HTTP请求的基本要素1.请求URL:客户端通过哪个路径找到服务器 2.请求参数:客户端发送给服务器的数据* 比如登录时需要发送的用户名和密码 3.返回结果:服务器返回给客户端的数据* 一般是 ...

  4. JSON、XML 解析

    iOS开发--XML/JSON数据解析 不错的文章http://www.jianshu.com/p/a54d367adb2a

  5. iOS - 分析JSON、XML的区别和解析方式的底层是如何实现的(延伸实现原理)

    <分析JSON.XML的区别,JSON.XML解析方式的底层是如何实现的(延伸实现原理)> (一)JSON与XML的区别: (1)可读性方面:基本相同,XML的可读性比较好: (2)可扩展 ...

  6. iOS XML解析使用-韩国庆

    欢迎-------(北京-iOS移动开发金牌教师QQ:2592675215)韩老师给你带来XML解析课程 今天给大家讲解下xml解析的第三方简单用法:首先我解释下,json和xml解析格式. JSON ...

  7. JSON解析和XML解析对比

    JSON解析和XML解析是较为普遍的两种解析方式,其中JSON解析的市场分额更大.本文系统的分析两种解析方式的区别,为更好地处理数据作准备.由于目前阶段主要是做移动开发,所以本文所描述的JSON解析和 ...

  8. iOS-数据持久化基础-JSON与XML数据解析

    解析的基本概念 所谓“解析”:从事先规定好的格式串中提取数据 解析的前提:提前约定好格式.数据提供方按照格式提供数据.数据获取方按照格式获取数据 iOS开发常见的解析:XML解析.JSON解析 一.X ...

  9. iOS开发——网络篇——JSON和XML,NSJSONSerialization ,NSXMLParser(XML解析器),NSXMLParserDelegate,MJExtension (字典转模型),GDataXML(三方框架解析XML)

    一.JSON 1.JSON简介什么是JSONJSON是一种轻量级的数据格式,一般用于数据交互服务器返回给客户端的数据,一般都是JSON格式或者XML格式(文件下载除外) JSON的格式很像OC中的字典 ...

随机推荐

  1. JS 时间 获取 当天,昨日,本周,上周,本月,上月

    调用 setTimeRange (2); function  setTimeRange (v) { var fmt = 'YYYY-MM-DD HH:mm'; var now = new Date() ...

  2. as2 无法加载类或接口

    1.最大问题就是可能新建文件的时候选择as3的as或者直接复制了as3的as文件过来修改.as文件必须是2的 2.类名是否一致 3.包引用是否正确

  3. as3 连接mysql

    http://www.cnblogs.com/yili16438/archive/2011/04/23/2025936.html

  4. SRC是在本位置显示:source的缩写,源的意思 HREF是点击后连接的目标:HyperlinkReference,超链接引用

    SRC是在本位置显示:source的缩写,源的意思HREF是点击后连接的目标:HyperlinkReference,超链接引用

  5. nginx访问静态文件配置

    通过nginx访问静态文件配置,均是在server模块中配置,有两种方式: 1.alias 通过alias关键字,重定义路径,如 server{     listen 7001;     server ...

  6. mongodb基础学习4-游标

    今天来讲讲游标的操作,可以先获取一组文档,再对每一个文档进行操作. 因为mongodb底层是js引擎,所有可以像操作js一样操作mongodb,比如插入数据 游标的使用:声明游标,判断是否有下一条数据 ...

  7. Haskell语言学习笔记(23)MonadReader, Reader, ReaderT

    MonadReader 类型类 class Monad m => MonadReader r m | m -> r where ask :: m r ask = reader id loc ...

  8. Eclipse 安装JavaEE插件

    Oxygen版Eclipse 导入项目会自动安装你项目需要的一些插件,但是有时候会安装失败,需要手动安装: 这里以Dynamic Web Project项目为例 打开Eclipse,依次选择Help ...

  9. ASP.Net 下载大文件的实现

    当我们的网站需要支持下载大文件时,如果不做控制可能会导致用户在访问下载页面时发生无响应,使得浏览器崩溃.可以参考如下代码来避免这个问题. 关于此代码的几点说明: 1. 将数据分成较小的部分,然后将其移 ...

  10. 吴裕雄 实战PYTHON编程(9)

    import cv2 cv2.namedWindow("ShowImage1")cv2.namedWindow("ShowImage2")image1 = cv ...