Json和XML解析
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上找,都有使用方法的说明的。
原文链接:http://www.jianshu.com/p/a54d367adb2a
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
Json和XML解析的更多相关文章
- 【.Net 】Json和Xml解析
引言 Json和Xml是现在跨平台传输数据的主流格式,关于它们的解析,网上资料很多,我稍作整理,写成一个小demo,方便日后使用. JSON解析 能进行json解析的类库有很多,例如Ja ...
- iOS - - JSON 和 XML解析
JSON 和 XML 一.JSON 1.什么是JSON JSON是一种轻量级的数据格式,一般用于数据交互 服务器返回给客户端的数据,一般都是JSON格式或者XML格式(文件下载除外) 2.JSON的格 ...
- 网络HTTP、JSON、XML解析等 复习
一.一个HTTP请求的基本要素1.请求URL:客户端通过哪个路径找到服务器 2.请求参数:客户端发送给服务器的数据* 比如登录时需要发送的用户名和密码 3.返回结果:服务器返回给客户端的数据* 一般是 ...
- JSON、XML 解析
iOS开发--XML/JSON数据解析 不错的文章http://www.jianshu.com/p/a54d367adb2a
- iOS - 分析JSON、XML的区别和解析方式的底层是如何实现的(延伸实现原理)
<分析JSON.XML的区别,JSON.XML解析方式的底层是如何实现的(延伸实现原理)> (一)JSON与XML的区别: (1)可读性方面:基本相同,XML的可读性比较好: (2)可扩展 ...
- iOS XML解析使用-韩国庆
欢迎-------(北京-iOS移动开发金牌教师QQ:2592675215)韩老师给你带来XML解析课程 今天给大家讲解下xml解析的第三方简单用法:首先我解释下,json和xml解析格式. JSON ...
- JSON解析和XML解析对比
JSON解析和XML解析是较为普遍的两种解析方式,其中JSON解析的市场分额更大.本文系统的分析两种解析方式的区别,为更好地处理数据作准备.由于目前阶段主要是做移动开发,所以本文所描述的JSON解析和 ...
- iOS-数据持久化基础-JSON与XML数据解析
解析的基本概念 所谓“解析”:从事先规定好的格式串中提取数据 解析的前提:提前约定好格式.数据提供方按照格式提供数据.数据获取方按照格式获取数据 iOS开发常见的解析:XML解析.JSON解析 一.X ...
- iOS开发——网络篇——JSON和XML,NSJSONSerialization ,NSXMLParser(XML解析器),NSXMLParserDelegate,MJExtension (字典转模型),GDataXML(三方框架解析XML)
一.JSON 1.JSON简介什么是JSONJSON是一种轻量级的数据格式,一般用于数据交互服务器返回给客户端的数据,一般都是JSON格式或者XML格式(文件下载除外) JSON的格式很像OC中的字典 ...
随机推荐
- UCenter 的目录结构
以下关于文件的阐述以及代码的样例,均以 PHP 程序为例. UCenter 的目录结构 UCenter 分为服务端和客户端 2 个部分.服务端目录为“upload/”,客户端目录为“client/ ...
- 11. SpringMVC拦截器(资源和权限管理)
1.DispatcherServlet SpringMVC具有统一的入口DispatcherServlet,所有的请求都通过DispatcherServlet. DispatcherServl ...
- win2008安装IIS
win2008安装IIS http://jingyan.baidu.com/article/fec4bce2398747f2618d8b88.html http://127.0.0.1/ 新建网站,端 ...
- delphi c++builder JSON 生成与解析 例子
json,System.JSON,REST.JSON JSON有两种数据结构,对象和数组. 对象在js中表示为“{}”括起来的内容,数据结构为 {key:value,key:value,...} 数组 ...
- eclipse 创建注释模板
使用 Alt+Shift+J 可以快速注释. 我们每次手动敲入作者,时间,版本等信息,有一些重复,可通过设置eclipse注释模板,减少工作量. Window -> preference -& ...
- 【Web缓存机制系列】2 – Web浏览器的缓存机制
Web缓存的工作原理 所有的缓存都是基于一套规则来帮助他们决定什么时候使用缓存中的副本提供服务(假设有副本可用的情况下,未被销毁回收或者未被删除修改).这些规则有的在协议中有定义(如HTTP协议1.0 ...
- HTTP状态码 解析
原文地址:HTTP状态码:400500错误代码(个人总结)作者:lining2008net 一些常见的状态码为: 200-服务器成功返回网页 404-请求的网页不存在 503-服务不可用 详细分解: ...
- clientdataset 用法
http://www.360doc.com/content/10/0709/01/2071424_37769962.shtml
- 使用CXF发布的WebService报错:org.apache.cxf.interceptor.Fault: The given SOAPAction does not match an operation
场景:JAVA语言使用CXF搭建WebService发布报错 错误信息:org.apache.cxf.interceptor.Fault: The given SOAPAction does not ...
- java学习笔记----@Override的作用
初学java或多或少都会有这样的疑问,@Override有什么用,有的时候写,有的时候又不写,搞的初学者甚是郁闷. 做了一两年的开发说起这个问题不一定能够对答如流.小弟才疏学浅,花了点时间,看了一下资 ...