一、XML简单介绍
XML:全称是Extensible Markup Language,译作“可扩展标记语言”
跟JSON一样,也是常用的一种用于交互的数据格式,一般也叫XML文档(XML Document)
XML举例
<videos>
<video name="小黄人 第01部" length="30" />
<video name="小黄人 第02部" length="19" />
<video name="小黄人 第03部" length="33" />
</videos>
二、XML的语法
1.简单说明
一个常见的XML文档一般由以下部分组成
文档声明
元素(Element)
属性(Attribute)
2.文档声明
在XML文档的最前面,必须编写一个文档声明,用来声明XML文档的类型
最简单的声明
<?xml version="1.0" ?>
用encoding属性说明文档的字符编码
<?xml version="1.0" encoding="UTF-8" ?>
3.XML语法 – 元素(Element)
一个元素包括了开始标签和结束标签
拥有元素内容:<video>小黄人</video>
没有元素内容:<video></video>
没有元素内容的简写:<video/>
一个元素可以嵌套若干个子元素(不能出现交叉嵌套)
<videos>
<video>
<name>小黄人 第01部</name>
<length>30</length>
</video>
</videos>
注意:
(1)规范的XML文档最多只有1个根元素,其他元素都是根元素的子孙元素
(2)XML中的所有空格和换行,都会当做具体内容处理
下面两个元素的内容是不一样的
第1个
<video>小黄人</video>
第2个
<video>
小黄人
</video>
4.XML语法 – 属性(Attribute)
一个元素可以拥有多个属性
<video name="小黄人 第01部" length="30" /> ====》video元素拥有name和length两个属性
注意:属性值必须用 双引号"" 或者 单引号'' 括住
实际上,属性表示的信息也可以用子元素来表示,比如
<video>
<name>小黄人 第01部</name>
<length>30</length>
</video>
三、XML的解析
1.简单说明
要想从XML中提取有用的信息,必须得学会解析XML
提取name元素里面的内容
<name>小黄人 第01部</name>
提取video元素中name和length属性的值
<video name="小黄人 第01部" length="30" />
XML的解析方式有2种
(1)DOM:一次性将整个XML文档加载进内存,比较适合解析小文件
(3)SAX:从根元素开始,按顺序一个元素一个元素往下解析,比较适合解析大文件
2.IOS开发中XML的解析
在iOS中,解析XML的手段有很多
(1)苹果原生 NSXMLParser:SAX方式解析,使用简单
(2)第三方框架
1)libxml2:纯C语言,默认包含在iOS SDK中,同时支持DOM和SAX方式解析
2)GDataXML:DOM方式解析,由Google开发,基于libxml2
XML解析方式的选择建议:
大文件:NSXMLParser、libxml2
小文件:GDataXML
3.NSXMLParser
(1)使用步骤
// 1.传入XML数据,创建解析器
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
// 2.设置代理,监听解析过程
parser.delegate = self;
// 3.开始解析
[parser parse];
(2)说明
NSXMLParser采取的是SAX方式解析,特点是事件驱动,下面情况都会通知代理
当扫描到文档(Document)的开始与结束
当扫描到元素(Element)的开始与结束
(3)NSXMLParserDelegate
1)当扫描到文档的开始时调用(开始解析)- (void)parserDidStartDocument:(NSXMLParser *)parser
2)当扫描到文档的结束时调用(解析完毕)- (void)parserDidEndDocument:(NSXMLParser *)parser
3)当扫描到元素的开始时调用(attributeDict存放着元素的属性)- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
4)当扫描到元素的结束时调用 - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
(4)代码示例
1 // 2 // YYViewController.m 3 // 01-文顶顶客户端 4 // 5 // Created by apple on 14-6-29. 6 // Copyright (c) 2014年 itcase. All rights reserved. 7 // 8 9 #import "YYViewController.h" 10 #import "MBProgressHUD+MJ.h" 11 #import "YYviodesModel.h" 12 #import "YYCell.h" 13 #import14 #import "YYMoviePlayerViewController.h" 15 16 @interface YYViewController () 17 @property(nonatomic,strong)NSArray *videos; 18 19 @end 20 21 @implementation YYViewController 22 23 - (void)viewDidLoad 24 { 25 [super viewDidLoad]; 26 //去掉下划线 27 self.tableView.separatorStyle=UITableViewCellSeparatorStyleNone; 28 29 [MBProgressHUD showMessage:@"正在努力加载中"]; 30 31 //创建路径 32 33 NSString *urlStr=@"http://192.168.1.53:8080/MJServer/video?type=XML"; 34 NSURL *url=[NSURL URLWithString:urlStr]; 35 36 //创建请求 37 NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:url];//默认为get请求 38 //设置最大的网络等待时间 39 request.timeoutInterval=20.0; 40 41 //获取主队列 42 NSOperationQueue *queue=[NSOperationQueue mainQueue]; 43 //发起请求 44 [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 45 //隐藏HUD 46 [MBProgressHUD hideHUD]; 47 if (data) {//如果请求成功,拿到服务器返回的数据 48 [self parseXMLData:data]; 49 50 // //解析拿到的数据(JSON方式) 51 // NSDictionary *dict=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil]; 52 NSArray *array=dict[@"video"]; 53 // NSArray *array=dict[@"videos"]; 54 // 55 // NSMutableArray *videos=[NSMutableArray array]; 56 // for (NSDictionary *dict in array) { 57 // YYviodesModel *model=[YYviodesModel viodesModelWithDict:dict]; 58 // [videos addObject:model]; 59 // } 60 // self.videos=videos; 61 62 //刷新表格 63 [self.tableView reloadData]; 64 65 }else//如果请求失败,没有拿到数据 66 { 67 [MBProgressHUD showError:@"网络繁忙,等稍后再试!"]; 68 } 69 }]; 70 } 71 72 /** 73 * 解析XML数据 74 */ 75 -(void)parseXMLData:(NSData *)data 76 { 77 //1.创建解析器 78 NSXMLParser *parser=[[NSXMLParser alloc]initWithData:data]; 79 //2.设置代理 80 parser.delegate=self; 81 82 //3.开始解析 83 [parser parse]; 84 } 85 86 #pragma mark-NSXMLParserDelegate 87 /** 88 *开始解析文档时调用 89 */ 90 -(void)parserDidStartDocument:(NSXMLParser *)parser 91 { 92 NSLog(@"开始解析文档"); 93 } 94 /** 95 *结束解析文档时调用(解析完毕) 96 */ 97 -(void)parserDidEndDocument:(NSXMLParser *)parser 98 { 99 NSLog(@"结束解析文档");100 }101 /**102 *解析到一个元素的开头时调用103 */104 -(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict105 {106 NSLog(@"解析到一个元素的开头---%@",elementName);107 }108 /**109 *解析到一个元素的结尾时调用110 */111 -(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName112 {113 NSLog(@"解析到一个元素的结尾---%@",elementName);114 }115 #pragma mark-数据源方法116 -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView117 {118 return 1;119 }120 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section121 {122 return self.videos.count;123 }124 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath125 {126 YYCell *cell=[YYCell cellWithTableView:tableView];127 //获取数据模型128 cell.model=self.videos[indexPath.row];129 return cell;130 }131 132 //设置cell的行高133 -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath134 {135 return 70;136 }137 138 //播放视频139 -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath140 {141 //取出数据模型142 YYviodesModel *model=self.videos[indexPath.row];143 144 //创建视屏播放器145 // MPMoviePlayerController 可以随意控制播放器的尺寸146 //MPMoviePlayerViewController只能全屏播放147 148 NSString *url = [NSString stringWithFormat:@"http://192.168.1.53:8080/MJServer/%@", model.url];149 NSURL *videoUrl=[NSURL URLWithString:url];150 YYMoviePlayerViewController *movieVc=[[YYMoviePlayerViewController alloc]initWithContentURL:videoUrl];151 //弹出播放器152 [self presentMoviePlayerViewControllerAnimated:movieVc];153 // UIApplicationDidEnterBackgroundNotification154 }155 156 157 @end
打印查看
(5)完成完整的功能
1 // 2 // YYViewController.m 3 // 01-文顶顶客户端 4 // 5 // Created by apple on 14-6-29. 6 // Copyright (c) 2014年 itcase. All rights reserved. 7 // 8 9 #import "YYViewController.h" 10 #import "MBProgressHUD+MJ.h" 11 #import "YYviodesModel.h" 12 #import "YYCell.h" 13 #import14 #import "YYMoviePlayerViewController.h" 15 16 @interface YYViewController () 17 @property(nonatomic,strong)NSMutableArray *videos; 18 19 @end 20 21 @implementation YYViewController 22 23 - (void)viewDidLoad 24 { 25 [super viewDidLoad]; 26 //去掉下划线 27 self.tableView.separatorStyle=UITableViewCellSeparatorStyleNone; 28 29 [MBProgressHUD showMessage:@"正在努力加载中"]; 30 31 //创建路径 32 33 NSString *urlStr=@"http://192.168.1.53:8080/MJServer/video?type=XML"; 34 NSURL *url=[NSURL URLWithString:urlStr]; 35 36 //创建请求 37 NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:url];//默认为get请求 38 //设置最大的网络等待时间 39 request.timeoutInterval=20.0; 40 41 //获取主队列 42 NSOperationQueue *queue=[NSOperationQueue mainQueue]; 43 //发起请求 44 [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 45 //隐藏HUD 46 [MBProgressHUD hideHUD]; 47 if (data) {//如果请求成功,拿到服务器返回的数据 48 //解析XML数据 49 [self parseXMLData:data]; 50 }else//如果请求失败,没有拿到数据 51 { 52 [MBProgressHUD showError:@"网络繁忙,等稍后再试!"]; 53 } 54 }]; 55 } 56 57 /** 58 * 解析XML数据 59 */ 60 -(void)parseXMLData:(NSData *)data 61 { 62 //1.创建解析器 63 NSXMLParser *parser=[[NSXMLParser alloc]initWithData:data]; 64 //2.设置代理 65 parser.delegate=self; 66 67 //3.开始解析 68 [parser parse]; //这个方法会卡住(同步解析,解析完毕后才会返回) 69 70 //4.刷新表格 71 [self.tableView reloadData]; 72 } 73 74 #pragma mark-NSXMLParserDelegate 75 /** 76 *开始解析文档时调用 77 */ 78 -(void)parserDidStartDocument:(NSXMLParser *)parser 79 { 80 NSLog(@"开始解析文档"); 81 } 82 /** 83 *结束解析文档时调用(解析完毕) 84 */ 85 -(void)parserDidEndDocument:(NSXMLParser *)parser 86 { 87 NSLog(@"结束解析文档"); 88 //也可以在这里刷新表格 89 // [self.tableView reloadData]; 90 } 91 /** 92 *解析到一个元素的开头时调用 93 */ 94 -(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict 95 { 96 // NSLog(@"解析到一个元素的开头---%@",elementName); 97 if ([@"videos" isEqualToString:elementName]) {//解析到一个videos标签 98 self.videos=[NSMutableArray array]; 99 }else if ([@"video" isEqualToString:elementName])100 {//解析到一个video标签,创建一个模型101 YYviodesModel *model=[YYviodesModel viodesModelWithDict:attributeDict];102 [self.videos addObject:model];103 }104 }105 /**106 *解析到一个元素的结尾时调用107 */108 -(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName109 {110 NSLog(@"解析到一个元素的结尾---%@",elementName);111 }112 #pragma mark-数据源方法113 -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView114 {115 return 1;116 }117 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section118 {119 return self.videos.count;120 }121 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath122 {123 YYCell *cell=[YYCell cellWithTableView:tableView];124 //获取数据模型125 cell.model=self.videos[indexPath.row];126 return cell;127 }128 129 //设置cell的行高130 -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath131 {132 return 70;133 }134 135 //播放视频136 -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath137 {138 //取出数据模型139 YYviodesModel *model=self.videos[indexPath.row];140 141 //创建视屏播放器142 // MPMoviePlayerController 可以随意控制播放器的尺寸143 //MPMoviePlayerViewController只能全屏播放144 145 NSString *url = [NSString stringWithFormat:@"http://192.168.1.53:8080/MJServer/%@", model.url];146 NSURL *videoUrl=[NSURL URLWithString:url];147 YYMoviePlayerViewController *movieVc=[[YYMoviePlayerViewController alloc]initWithContentURL:videoUrl];148 //弹出播放器149 [self presentMoviePlayerViewControllerAnimated:movieVc];150 // UIApplicationDidEnterBackgroundNotification151 }152 153 154 @end
注意:注意刷新代码的操作,在进行解析的时候,需要对标签进行判断。
四、基于NSXMLParser(SAX)封装解析数据的代码(包括JSON和XML的解析)
封装后的主控制器代码:
1 // 2 // YYViewController.m 3 // 01-文顶顶客户端 4 // 5 // Created by apple on 14-6-29. 6 // Copyright (c) 2014年 itcase. All rights reserved. 7 // 8 9 #import "YYViewController.h" 10 #import "MBProgressHUD+MJ.h" 11 #import "YYviodesModel.h" 12 #import "YYCell.h" 13 #import14 #import "YYMoviePlayerViewController.h" 15 #import "YYtool.h" 16 17 @interface YYViewController () 18 @property(nonatomic,strong)NSArray *videos; 19 @end 20 21 @implementation YYViewController 22 23 -(NSArray *)videos 24 { 25 if (_videos==nil) { 26 _videos=[NSArray array]; 27 } 28 return _videos; 29 } 30 - (void)viewDidLoad 31 { 32 [super viewDidLoad]; 33 //去掉下划线 34 self.tableView.separatorStyle=UITableViewCellSeparatorStyleNone; 35 36 [MBProgressHUD showMessage:@"正在努力加载中"]; 37 38 //创建路径 39 40 NSString *urlStr=@"http://192.168.1.53:8080/MJServer/video?type=JSON"; 41 NSURL *url=[NSURL URLWithString:urlStr]; 42 43 //创建请求 44 NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:url];//默认为get请求 45 //设置最大的网络等待时间 46 request.timeoutInterval=20.0; 47 48 //获取主队列 49 NSOperationQueue *queue=[NSOperationQueue mainQueue]; 50 //发起请求 51 [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 52 //隐藏HUD 53 [MBProgressHUD hideHUD]; 54 if (data) {//如果请求成功,拿到服务器返回的数据 55 //解析XML数据 56 YYtool *tool=[[YYtool alloc]init]; 57 // [tool parseXMLData:data]; 58 self.videos=[tool parseJSONData:data]; 59 //刷新表格 60 [self.tableView reloadData]; 61 }else//如果请求失败,没有拿到数据 62 { 63 [MBProgressHUD showError:@"网络繁忙,等稍后再试!"]; 64 } 65 }]; 66 } 67 68 69 #pragma mark-数据源方法 70 -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 71 { 72 return 1; 73 } 74 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 75 { 76 return self.videos.count; 77 } 78 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 79 { 80 YYCell *cell=[YYCell cellWithTableView:tableView]; 81 //获取数据模型 82 cell.model=self.videos[indexPath.row]; 83 return cell; 84 } 85 86 //设置cell的行高 87 -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 88 { 89 return 70; 90 } 91 92 //播放视频 93 -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 94 { 95 //取出数据模型 96 YYviodesModel *model=self.videos[indexPath.row]; 97 98 //创建视屏播放器 99 // MPMoviePlayerController 可以随意控制播放器的尺寸100 //MPMoviePlayerViewController只能全屏播放101 102 NSString *url = [NSString stringWithFormat:@"http://192.168.1.53:8080/MJServer/%@", model.url];103 NSURL *videoUrl=[NSURL URLWithString:url];104 YYMoviePlayerViewController *movieVc=[[YYMoviePlayerViewController alloc]initWithContentURL:videoUrl];105 //弹出播放器106 [self presentMoviePlayerViewControllerAnimated:movieVc];107 // UIApplicationDidEnterBackgroundNotification108 }109 @end
封装的解析类的头文件
1 // 2 // YYtool.h 3 // 01-文顶顶客户端 4 // 5 // Created by apple on 14-6-29. 6 // Copyright (c) 2014年 itcase. All rights reserved. 7 // 8 9 #import10 11 @interface YYtool : NSObject12 -(NSArray *)parseXMLData:(NSData *)data;13 -(NSArray *)parseJSONData:(NSData *)data;14 15 @end
封装的解析类的内部实现:
1 // 2 // YYtool.m 3 // 01-文顶顶客户端 4 // 5 // Created by apple on 14-6-29. 6 // Copyright (c) 2014年 itcase. All rights reserved. 7 // 8 9 #import "YYtool.h"10 #import "YYviodesModel.h"11 12 @interface YYtool ()13 @property(nonatomic,strong)NSMutableArray *videos;14 @end15 @implementation YYtool16 17 -(NSArray *)parseJSONData:(NSData *)data18 {19 NSDictionary *dict=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];20 // NSArray *array=dict[@"video"];21 NSArray *array=dict[@"videos"];22 23 NSMutableArray *videos=[NSMutableArray array];24 for (NSDictionary *dict in array) {25 YYviodesModel *model=[YYviodesModel viodesModelWithDict:dict];26 [videos addObject:model];27 }28 return videos;29 }30 31 -(NSArray *)parseXMLData:(NSData *)data32 {33 //1.创建解析器34 NSXMLParser *parser=[[NSXMLParser alloc]initWithData:data];35 //2.设置代理36 parser.delegate=self;37 38 //3.开始解析39 [parser parse]; //这个方法会卡住(同步解析,解析完毕后才会返回)40 41 return self.videos;42 }43 44 #pragma mark-NSXMLParserDelegate45 /**46 *开始解析文档时调用47 */48 -(void)parserDidStartDocument:(NSXMLParser *)parser49 {50 NSLog(@"开始解析文档");51 }52 /**53 *结束解析文档时调用(解析完毕)54 */55 -(void)parserDidEndDocument:(NSXMLParser *)parser56 {57 NSLog(@"结束解析文档");58 //也可以在这里刷新表格59 // [self.tableView reloadData];60 }61 /**62 *解析到一个元素的开头时调用63 */64 -(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict65 {66 if ([@"videos" isEqualToString:elementName]) {//解析到一个videos标签67 self.videos=[NSMutableArray array];68 }else if ([@"video" isEqualToString:elementName])69 {//解析到一个video标签,创建一个模型70 YYviodesModel *model=[YYviodesModel viodesModelWithDict:attributeDict];71 [self.videos addObject:model];72 }73 }74 /**75 *解析到一个元素的结尾时调用76 */77 -(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName78 {79 NSLog(@"解析到一个元素的结尾---%@",elementName);80 }81 82 @end
五、GDataXML
1.配置
GDataXML基于libxml2库,得做以下配置
导入libxml2库
该动态库内部没有头文件,所以还需要设置libxml2的头文件搜索路径(为了能找到libxml2库的所有头文件)
在Head Search Path中加入/usr/include/libxml2
该库是2008年的,未使用ARC进行内存管理,所以还需要告诉编译器,对它进行非ARC处理。
设置链接参数(自动链接libxml2库)
在Other Linker Flags中加入-lxml2
2.GDataXML使用
GDataXML中常用的类
GDataXMLDocument:代表整个XML文档
GDataXMLElement
代表文档中的每个元素
使用attributeForName:方法可以获得属性值
代码示例:
1 // 2 // YYViewController.m 3 // 01-文顶顶客户端 4 // 5 // Created by apple on 14-6-29. 6 // Copyright (c) 2014年 itcase. All rights reserved. 7 // 8 9 #import "YYViewController.h" 10 #import "MBProgressHUD+MJ.h" 11 #import "YYviodesModel.h" 12 #import "YYCell.h" 13 #import14 #import "YYMoviePlayerViewController.h" 15 #import "GDataXMLNode.h" 16 17 @interface YYViewController () 18 @property(nonatomic,strong)NSMutableArray *videos; 19 20 @end 21 22 @implementation YYViewController 23 24 - (void)viewDidLoad 25 { 26 [super viewDidLoad]; 27 //去掉下划线 28 self.tableView.separatorStyle=UITableViewCellSeparatorStyleNone; 29 30 [MBProgressHUD showMessage:@"正在努力加载中"]; 31 32 //创建路径 33 34 NSString *urlStr=@"http://192.168.1.53:8080/MJServer/video?type=XML"; 35 NSURL *url=[NSURL URLWithString:urlStr]; 36 37 //创建请求 38 NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:url];//默认为get请求 39 //设置最大的网络等待时间 40 request.timeoutInterval=20.0; 41 42 //获取主队列 43 NSOperationQueue *queue=[NSOperationQueue mainQueue]; 44 //发起请求 45 [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 46 //隐藏HUD 47 [MBProgressHUD hideHUD]; 48 if (data) {//如果请求成功,拿到服务器返回的数据 49 //解析XML数据 50 [self parseXMLData:data]; 51 }else//如果请求失败,没有拿到数据 52 { 53 [MBProgressHUD showError:@"网络繁忙,等稍后再试!"]; 54 } 55 }]; 56 } 57 58 /** 59 * DOM方式解析XML数据 60 */ 61 -(void)parseXMLData:(NSData *)data 62 { 63 //1.加载文档 64 GDataXMLDocument *doc=[[GDataXMLDocument alloc]initWithData:data options:0 error:nil]; 65 //2.获得根元素 66 GDataXMLElement *root=doc.rootElement; 67 //3.获得所有的video元素 68 NSArray *elements=[root elementsForName:@"video"]; 69 //4.将GDataXMLElement对象转换成模型 70 NSMutableArray *videos=[NSMutableArray array]; 71 for (GDataXMLElement *ele in elements) { 72 YYviodesModel *model=[[YYviodesModel alloc]init]; 73 model.ID=[ele attributeForName:@"id"].stringValue.intValue; 74 model.length=[ele attributeForName:@"length"].stringValue.intValue; 75 model.name=[ele attributeForName:@"name"].stringValue; 76 model.image=[ele attributeForName:@"image"].stringValue; 77 model.url=[ele attributeForName:@"url"].stringValue; 78 [videos addObject:model]; 79 } 80 self.videos=videos; 81 //4.刷新表格 82 [self.tableView reloadData]; 83 } 84 85 #pragma mark-数据源方法 86 -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 87 { 88 return 1; 89 } 90 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 91 { 92 return self.videos.count; 93 } 94 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 95 { 96 YYCell *cell=[YYCell cellWithTableView:tableView]; 97 //获取数据模型 98 cell.model=self.videos[indexPath.row]; 99 return cell;100 }101 102 //设置cell的行高103 -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath104 {105 return 70;106 }107 108 //播放视频109 -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath110 {111 //取出数据模型112 YYviodesModel *model=self.videos[indexPath.row];113 114 //创建视屏播放器115 // MPMoviePlayerController 可以随意控制播放器的尺寸116 //MPMoviePlayerViewController只能全屏播放117 118 NSString *url = [NSString stringWithFormat:@"http://192.168.1.53:8080/MJServer/%@", model.url];119 NSURL *videoUrl=[NSURL URLWithString:url];120 YYMoviePlayerViewController *movieVc=[[YYMoviePlayerViewController alloc]initWithContentURL:videoUrl];121 //弹出播放器122 [self presentMoviePlayerViewControllerAnimated:movieVc];123 // UIApplicationDidEnterBackgroundNotification124 }125 @end
执行:
网络应用中的数据解析,因为最近的应用,无论是Android的和ios平台的,一直用也是建议用的都是Json解析,
xml解析都有点被遗忘了。
然后最近自己在做着玩一个ios的小应用,涉及网络数据的抓取,一些网站可能都提供了自己api平台,这些一般都是支持
我们对于数据协议格式的设定的。但是后来我在找寻到一些Rss资源时,发现返回的数据都是xml格式的,
因此,那就只好用xml解析了。
XML解析其实这个概念出现了算够久了,以前javaweb什么到处都在用。这边我们主要大致介绍下,然后在在ios编程如何使用。
XML解析一般分两种模式SAX和DOM,事件和文档。具体解析google去吧,有详细。不过看了下面的两个例子,一般就了解了。
一:XML解析之SAX解析,以及对NSXMLParser的应用。
sax解析说白了,就是一个事物模型解析,从头开始读取文档然后根据读取到的头标签标签时要怎么处理,读完头标签后,理论上是读取标签值了,
然后读取后遇到结束标签等
简单举个例子
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"> 头标签,里面的xmlns,可以看成是属性
<channel><title>呵呵呵呵</title>结束标签,中间的“呵呵呵呵”是首尾标签标签值空间.......
好了,那么在ios开发中如何使用。
SDK本身是提供了NSXMLParser解析器。
- -(BOOL)parser:(NSString*)string
- {
- //系统自带的
- NSXMLParser *par = [[[NSXMLParser alloc] initWithData:[string dataUsingEncoding:NSUTF8StringEncoding]]autorelease];
- [par setDelegate:self];//设置NSXMLParser对象的解析方法代理
- return [par parse];//调用代理解析NSXMLParser对象,看解析是否成功 }
- }
- #pragma mark xmlparser
- //step 1 :准备解析
- - (void)parserDidStartDocument:(NSXMLParser *)parser
- {
- // NSLog(@"%@",NSStringFromSelector(_cmd) );
- }
- //step 2:准备解析节点
- - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
- {
- // NSLog(@"%@",NSStringFromSelector(_cmd) );
- }
- //step 3:获取首尾节点间内容
- - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
- {
- NSLog(@"%@",NSStringFromSelector(_cmd) );
- }
- //step 4 :解析完当前节点
- - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
- {
- NSLog(@"%@",NSStringFromSelector(_cmd) );
- }
- //step 5;解析结束
- - (void)parserDidEndDocument:(NSXMLParser *)parser
- {
- // NSLog(@"%@",NSStringFromSelector(_cmd) );
- }
- //获取cdata块数据
- - (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock
- {
- // NSLog(@"%@",NSStringFromSelector(_cmd) );
- }
2.parse,启动解析,返回一个是否解析成功Bool值。
3.基本你要处理的就在下面实现的1-5个代理方法了。
其实代理方法和详细,就是一个事物进行流程:
step1是准备解析,然后没意外就是执行到了——>
step2读取到第一个头节点了,然后如果内部有属性值,你可以获取出来,读完头节点,我们会进去值域——》
step3对于简单的节点,可能直接就是一个string值了,但是看例子我们会知道,很多情况下,该节点的值域包含的于是一个节点——》
这步其实分两种,如果是值,那么就是执行step4,获取值的字窜,如果是子节点呢,我们一看就知道,它又是进行了step2,
即读取到头标签了,其实你是很人读一片文章流程一样,只不过我们脑中有个印象<xxx>是头标签了,我们要做什么,独到 头标签的最后一个符号">"
下面进去值域,独到了字窜的话就调用了foundCharacters:(NSString *)string,如果又读到<xxx>这样的,那就又是头标签了。——》
step5就是读到开始尾标签符号了。
最后一个方法
foundCDATA:(NSData *)CDATABlock,其实也是一个格式
- <content:encoded>
- <![CDATA[
- <img src="http://img1.douban.com/mpic/s10489201.jpg" style="float:right;margin-left:16px"/><a href="http://www.douban.com/people/maldini/">减卐肥™</a>评论: <a href="http://movie.douban.com/subject/6799191//">搜索</a><br/> <br/>评价: 力荐<br/><br/>
- ]]>
- </content:encoded>
- <channel>
- <title>我是标题</title>
- <link>http://write.blog.csdn.net/postedit</link>
- <description>...</description>
- <language>zh-cn</language>
- <pubDate>Fri, 03 Aug 2012 06:20:31 GMT</pubDate>
- <item>...</item>
- <item>...</item>
- <item>...</item>
- <item>...</item>
- <item>...</item>
- <item>...</item>
- <item>...</item>
- <item>...</item>
- <item>...</item>
- <item>...</item>
- <item>...</item>
- <item>...</item>
- <item>...</item>
- <item>...</item>
- <item>...</item>
- <item>...</item>
- <item>...</item>
- <item>...</item>
- <item>...</item>
- <item>...</item>
- </channel>
- #pragma mark xmlparser
- //step 1 :准备解析
- - (void)parserDidStartDocument:(NSXMLParser *)parser
- {
- // NSLog(@"%@",NSStringFromSelector(_cmd) );
- parserObjects = [[NSMutableArray alloc]init];
- }
- //step 2:准备解析节点
- - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
- {
- // NSLog(@"%@",NSStringFromSelector(_cmd) );
- self.currentText = [[NSMutableString alloc]init];
- [currentText release];
- if ([elementName isEqualToString:@"item"]) {
- NSMutableDictionary *newNode = [[ NSMutableDictionary alloc ] initWithCapacity : 0 ];
- twitterDic = newNode;
- [parserObjects addObject :newNode];
- [newNode release];
- }
- else if(twitterDic) {
- NSMutableString *string = [[ NSMutableString alloc ] initWithCapacity : 0 ];
- [twitterDic setObject :string forKey :elementName];
- [string release ];
- currentElementName = elementName;
- }
- }
- //step 3:获取首尾节点间内容
- - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
- {
- NSLog(@"%@",NSStringFromSelector(_cmd) );
- [currentText appendString:string];
- }
- //step 4 :解析完当前节点
- - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
- {
- if ([elementName isEqualToString:@"item"]) {
- twitterDic = nil;
- }else
- if ([elementName isEqualToString:currentElementName]) {
- if ([elementName isEqualToString:@"description"]
- ||[elementName isEqualToString:@"content:encoded"]) {
- [twitterDic setObject:Cdata forKey:currentElementName];
- }else {
- [twitterDic setObject:currentText forKey:currentElementName];
- }
- }
- }
- //step 5;解析结束
- - (void)parserDidEndDocument:(NSXMLParser *)parser
- {
- }
- //获取cdata块数据
- - (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock
- {
- Cdata =[[NSString alloc] initWithData:CDATABlock encoding:NSUTF8StringEncoding];
- }
- //- (void)recurrence:(TBXMLElement *)element {
- //
- // NSString *eleName = [TBXML elementName:element];
- // NSString *eleText = [TBXML textForElement:element];
- // if ([eleName isEqualToString:@"item"]) {
- // self recurrence:element
- // }
- //
- //
- //
- //
- // do {
- //
- // NSString *eleName = [TBXML elementName:element];
- // NSString *eleText = [TBXML textForElement:element];
- //
- // //递归处理子树
- // if (element->firstChild) {
- // NSLog(@"<%@>:",eleName);// Display the name of the element
- //
- // [self recurrence:element->firstChild];
- // }else {
- // NSLog(@"<%@>:%@",eleName,eleText);// Display the name of the element
- //
- // TBXMLElement *parent = element->parentElement;
- // if ([[TBXML elementName:parent] isEqualToString:@"item"]) {
- // NLRssInfo *info = [[[NLRssInfo alloc]init] autorelease];
- //
- // if ([eleName isEqualToString:@"title"]) {
- // info.title = eleText;
- // }
- //
- //
- // [dataArr addObject:info];
- // }
- //
- // }
- //
- //
- // //迭代处理兄弟树
- // } while ((element = element->nextSibling));
- //}