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](http://download.csdn.net/detail/zhixinhuacom/9417644),并 解压将其中的GDataXMLNode.h 和 GDataXMLNode.m文件拖到项目中。
2、由于GDataXML基于libxml2库,因此要导入libxml2
![](https://box.kancloud.cn/2016-03-07_56dd401233131.jpg)
3、设置libxml2的头文件搜索路径(为了能找到libxml2库的所有头文件)
在**Head Search Path**中加入/usr/include/libxml2
![](https://box.kancloud.cn/2016-03-07_56dd40124e2e7.jpg)
4、设置链接参数(自动链接libxml2库)
在**Other Linker Flags**中加入-lxml2
![](https://box.kancloud.cn/2016-03-07_56dd401279dd7.jpg)
5、如果报arc错误,则设置GDataXML编译参数
![](https://box.kancloud.cn/2016-03-07_56dd40129d19e.jpg)
6、导入#import "GDataXMLNode.h" 头文件就可以使用了。
例子:
解析下面格式的xml
![](https://box.kancloud.cn/2016-03-07_56dd4012bd5ad.jpg)
~~~
-(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
~~~
解析输入结果:
![](https://box.kancloud.cn/2016-03-07_56dd40130638a.jpg)![](https://box.kancloud.cn/2016-03-07_56dd40133586f.jpg)
- 前言
- iOS开发实践之SQLite3
- iOS开发实践之FMDB
- Obj-C与javascript交互之WebViewJavascriptBridge
- iOS开发实践之UIWebView
- iOS开发实践之多线程(基本概念)
- iOS开发实践之多线程(NSThread)
- iOS开发实践之多线程(GCD)
- iOS开发实践之多线程(单例模式)
- iOS开发实践之xib加载注意问题
- iOS开发实践之多线程(NSOperation)
- iOS开发实践之cell下载图片(NSOperation)
- iOS开发实践之cell下载图片(自定义NSOperation)
- iOS开发实践之cell下载图片(SDWebImage)
- iOS开发实践之JSON
- iOS开发实践之XML
- iOS开发实践之GET和POST请求
- iOS开发实践之网络检测Reachability
- iOS开发实践之MD5加密