iOS开发实践之XML
2016-01-25 23:31
561 查看
xml与json的对比,前面文章已经提供参考,至于xml的语法结构也不在这详述。 直奔iOS中解析xml的方法。
iOS中的XML解析(Dom和SAX)
Dom方式使用的是文档对象模型解析,它首先要将xml文件整个读入内存中,然后再来构建Dom对象,在DOM对象里,xml文件中的所有元素都可以当做节点(Node)对象来处理。这种方式优点是方便对文档进行增加、删除、修改、添加等操作,缺点是它首先要将整个文件读入内存中在解析,如果文件大。会很消耗内存,并且它的执行速度慢。
SAX解析XML文件采用事件驱动的方式进行,也就是说,SAX是逐行扫描文件,遇到符合条件的设定条件后就会触发特定的事件,回调你写好的事件处理程 序。使用SAX的优势在于其解析速度较快,占用内存较少(相对于DOM而言)。而且SAX在解析文件的过程中得到自己需要的信息后可以随时终止解析,并不 一定要等文件全部解析完毕。凡事有利必有弊,其劣势在于SAX采用的是流式处理方式,当遇到某个标签的时候,它并不会记录下以前所遇到的标签,也就是说, 在处理某个标签的时候,所能够得到的信息就是标签的名字和属性,至于标签内部的嵌套结构,上层标签、下层标签以及其兄弟节点的名称等等与其结构 相关的信息都是不得而知的。实际上就是把XML文件的结构信息丢掉了,如果需要得到这些信息的话,只能你自己在程序里进行处理了。所以相对DOM而 言,SAX处理XML文档没有DOM方便,SAX处理的过程相对DOM而言也比较复杂。
总结:
DOM:一次性将整个XML文档加载进内存,比较适合解析小文件
SAX:SAX采用事件驱动,从根元素开始,按顺序一个元素一个元素往下解析,比较适合解析大文件。
解析方法:
苹果原生
NSXMLParser:SAX方式解析,使用简单
第三方框架
libxml2:纯C语言,默认包含在iOS SDK中,同时支持DOM和SAX方式解析
GDataXML:DOM方式解析,由Google开发,基于libxml2
XML解析方式的选择建议
大文件:NSXMLParser、libxml2
小文件:GDataXML
GDataXML:
常用的类
GDataXMLDocument:代表整个XML文档
GDataXMLElement:代表文档中的每个元素
常用方法:
elementsForName:根据元素名称得到元素节点
attributeForName:方法可以获得属性值
更多的操作xml的方法和属性,查阅GDataXMLNode.h
使用步骤:
1、下载GDataXMLNode ,下载地址:http://download.csdn.net/detail/zhixinhuacom/9417644,并 解压将其中的GDataXMLNode.h 和 GDataXMLNode.m文件拖到项目中。
2、由于GDataXML基于libxml2库,因此要导入libxml2
3、设置libxml2的头文件搜索路径(为了能找到libxml2库的所有头文件)
在Head Search Path中加入/usr/include/libxml2
4、设置链接参数(自动链接libxml2库)
在Other Linker Flags中加入-lxml2
5、如果报arc错误,则设置GDataXML编译参数
6、导入#import "GDataXMLNode.h" 头文件就可以使用了。
例子:
解析下面格式的xml
NSXMLParser:
NSXMLParser采取的是SAX方式解析,特点是事件驱动,下面情况都会通知代理:
(1)当扫描到文档(Document)的开始与结束
(2)当扫描到元素(Element)的开始与结束
一:使用步骤:
1、传入XML数据,创建解析器
NSXMLParser *parser = [[NSXMLParseralloc]
initWithData:data];
2、设置代理,监听解析过程
parser.delegate =self;
3、开始解析
[parserparse];
二:NSXMLParserDelegate常用代理方法:
当扫描到文档的开始时调用(开始解析)
- (void)parserDidStartDocument:(NSXMLParser *)parser
当扫描到文档的结束时调用(解析完毕)
- (void)parserDidEndDocument:(NSXMLParser *)parser
当扫描到元素的开始时调用(attributeDict存放着元素的属性)
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString
*)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
当扫描到元素的结束时调用
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString
*)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
例子:同样解析上面格式的xml
解析输入结果:
iOS中的XML解析(Dom和SAX)
Dom方式使用的是文档对象模型解析,它首先要将xml文件整个读入内存中,然后再来构建Dom对象,在DOM对象里,xml文件中的所有元素都可以当做节点(Node)对象来处理。这种方式优点是方便对文档进行增加、删除、修改、添加等操作,缺点是它首先要将整个文件读入内存中在解析,如果文件大。会很消耗内存,并且它的执行速度慢。
SAX解析XML文件采用事件驱动的方式进行,也就是说,SAX是逐行扫描文件,遇到符合条件的设定条件后就会触发特定的事件,回调你写好的事件处理程 序。使用SAX的优势在于其解析速度较快,占用内存较少(相对于DOM而言)。而且SAX在解析文件的过程中得到自己需要的信息后可以随时终止解析,并不 一定要等文件全部解析完毕。凡事有利必有弊,其劣势在于SAX采用的是流式处理方式,当遇到某个标签的时候,它并不会记录下以前所遇到的标签,也就是说, 在处理某个标签的时候,所能够得到的信息就是标签的名字和属性,至于标签内部的嵌套结构,上层标签、下层标签以及其兄弟节点的名称等等与其结构 相关的信息都是不得而知的。实际上就是把XML文件的结构信息丢掉了,如果需要得到这些信息的话,只能你自己在程序里进行处理了。所以相对DOM而 言,SAX处理XML文档没有DOM方便,SAX处理的过程相对DOM而言也比较复杂。
总结:
DOM:一次性将整个XML文档加载进内存,比较适合解析小文件
SAX:SAX采用事件驱动,从根元素开始,按顺序一个元素一个元素往下解析,比较适合解析大文件。
解析方法:
苹果原生
NSXMLParser:SAX方式解析,使用简单
第三方框架
libxml2:纯C语言,默认包含在iOS SDK中,同时支持DOM和SAX方式解析
GDataXML:DOM方式解析,由Google开发,基于libxml2
XML解析方式的选择建议
大文件:NSXMLParser、libxml2
小文件:GDataXML
GDataXML:
常用的类
GDataXMLDocument:代表整个XML文档
GDataXMLElement:代表文档中的每个元素
常用方法:
elementsForName:根据元素名称得到元素节点
attributeForName:方法可以获得属性值
更多的操作xml的方法和属性,查阅GDataXMLNode.h
使用步骤:
1、下载GDataXMLNode ,下载地址:http://download.csdn.net/detail/zhixinhuacom/9417644,并 解压将其中的GDataXMLNode.h 和 GDataXMLNode.m文件拖到项目中。
2、由于GDataXML基于libxml2库,因此要导入libxml2
3、设置libxml2的头文件搜索路径(为了能找到libxml2库的所有头文件)
在Head Search Path中加入/usr/include/libxml2
4、设置链接参数(自动链接libxml2库)
在Other Linker Flags中加入-lxml2
5、如果报arc错误,则设置GDataXML编译参数
6、导入#import "GDataXMLNode.h" 头文件就可以使用了。
例子:
解析下面格式的xml
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ NSURL *url = [NSURL URLWithString:@"http://localhost:8080/myService/video?type=XML"]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) { //1、加载xml数据 GDataXMLDocument *document = [[GDataXMLDocument alloc]initWithData:data options:0 error:nil]; //2、获取xml根元素(videos) GDataXMLElement *root = document.rootElement; // //元素子节点个数(不包括子节点下的节点) // NSInteger childCount = root.childCount; // //元素名称 // NSString *elementName = root.name; // //节点内容字符串 // NSString *xmlStr = root.XMLString; // NSLog(@"childCount=%ld\nelementName=%@\nxmlStr=%@",childCount,elementName,xmlStr); //3、获取根元素的所有video元素 NSArray *elements = [root elementsForName:@"video"]; for (GDataXMLElement *element in elements) { //4、获取属性植 NSString *idStr = [element attributeForName:@"id"].stringValue; NSString *name = [element attributeForName:@"name"].stringValue; NSString *length = [element attributeForName:@"length"].stringValue; NSString *image = [element attributeForName:@"image"].stringValue; NSString *url = [element attributeForName:@"url"].stringValue; NSLog(@"id=%@",idStr); NSLog(@"name=%@",name); NSLog(@"length=%@",length); NSLog(@"image=%@",image); NSLog(@"url=%@",url); } }]; }
NSXMLParser:
NSXMLParser采取的是SAX方式解析,特点是事件驱动,下面情况都会通知代理:
(1)当扫描到文档(Document)的开始与结束
(2)当扫描到元素(Element)的开始与结束
一:使用步骤:
1、传入XML数据,创建解析器
NSXMLParser *parser = [[NSXMLParseralloc]
initWithData:data];
2、设置代理,监听解析过程
parser.delegate =self;
3、开始解析
[parserparse];
二:NSXMLParserDelegate常用代理方法:
当扫描到文档的开始时调用(开始解析)
- (void)parserDidStartDocument:(NSXMLParser *)parser
当扫描到文档的结束时调用(解析完毕)
- (void)parserDidEndDocument:(NSXMLParser *)parser
当扫描到元素的开始时调用(attributeDict存放着元素的属性)
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString
*)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
当扫描到元素的结束时调用
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString
*)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
例子:同样解析上面格式的xml
#import "ViewController.h" @interface ViewController ()<NSXMLParserDelegate> @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. } -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ NSURL *url = [NSURL URLWithString:@"http://localhost:8080/myService/video?type=XML"]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) { //1、传入xml,创建解析器 NSXMLParser *parser = [[NSXMLParser alloc]initWithData:data]; //2、设置代理、监听解析过程 parser.delegate = self; //3、开始解析 [parser parse]; }]; } #pragma mark NSXMLParserDelegate代理方法 //当扫描到元素的开始时调用(attributeDict存放着元素的属性) -(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict{ NSLog(@"===========%@元素开始解析========",elementName); if ([@"videos" isEqualToString:elementName]) { NSLog(@"%@是根节点",elementName); return; } NSString *idStr = attributeDict[@"id"]; NSString *name = attributeDict[@"name"]; NSString *length = attributeDict[@"length"]; NSString *image = attributeDict[@"image"]; NSString *urlStr = attributeDict[@"url"]; NSLog(@" \n id=%@ \n name=%@\n length=%@ \n image=%@ \n url=%@",idStr,name,length,image,urlStr); }; //当扫描到元素的结束时调用 -(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{ NSLog(@"===========%@元素解析结束========",elementName); } //当扫描到文档的开始时调用(开始解析) -(void)parserDidStartDocument:(NSXMLParser *)parser{ NSLog(@"parserDidStartDocument=====开始解析======="); } //当扫描到文档的结束时调用(解析完毕) -(void)parserDidEndDocument:(NSXMLParser *)parser{ NSLog(@"parserDidEndDocument=====解析完毕========"); } @end
解析输入结果:
相关文章推荐
- 浅析 协议和block的反向传值
- WWDC心得与延伸:iOS图形性能
- 蓝懿ios技术交流和心得分享16.1.25
- ios 合并静态库
- [iOS]ARC和MRC下混编
- 关于iOS遮罩的实现与透明度为0时自己的理解
- iOS CGRectDivide布局(代码举例)
- iOS项目开发流程和发布流程
- [iOS]为什么不要在init初始化方法里调用self.view
- iOS中多控制器的使用
- 献给初学iOS的小盆友们——微博app项目开发之八封装代码
- iOS实现空闲超时自动登出
- 遍历iOS相册
- xcode 发展史 及 做iOS 必须知道的小知识
- IOS7的转场动画和CATransform3D简单使用
- iOS支付宝
- ios app崩溃的时候如何通过代码层面确定崩溃位置
- iOS crash 崩溃问题的追踪方法
- iOS开发何如在调试的时候轻松找到程序在哪里崩溃
- IOS安全–使用class-dump-z导出IOS应用类信息