XML解析(SAX)
2015-09-18 15:28
288 查看
目标
得到一个video的数组
包含很多个video对象
每一个video对象的内容是包含在video节点之间的
1. 开始文档
准备工作
2. 开始节点
新建一个 video 对象
可以设置 videoId 的属性
name
3. 发现节点文字
发现每一个节点的内容字符串
拼接字符串的工作
XML 解析的思路
目标
得到一个video的数组
包含很多个video对象
每一个video对象的内容是包含在video节点之间的
1. 开始文档
准备工作
2. 开始节点
新建一个 video 对象
可以设置 videoId 的属性
name
3. 发现节点文字
发现每一个节点的内容字符串
拼接字符串的工作
4. 结束节点
如果第2步是name
第3步拼接出来的字符串,就是要设置给name的完整内容
如果第2步是lenght
第3步拼接出来的字符串,就是要设置给length的完整内容
如果第2步是videoURL
第3步拼接出来的字符串,就是要设置给videoURL的完整内容
对应的属性内容可以在第4步进行设置数值
如果是video
将第2步创建的 video 对象添加到数组
5. 结束文档
所有内容解析完成,得到一个完整的数组
问题
1. 在那一个步骤,创建 video 对象比较合适
需要素材
1. 要有一个可变的数组,存放所有生成的video对象
2. 要一个可变的字符串,在第三步骤拼接字符串
3. 需要一个当前正在解析的video对象
在第2步创建
第3步拼接内容
第4步设置属性/添加到数组
4. 结束节点
如果第2步是name
第3步拼接出来的字符串,就是要设置给name的完整内容
如果第2步是lenght
第3步拼接出来的字符串,就是要设置给length的完整内容
如果第2步是videoURL
第3步拼接出来的字符串,就是要设置给videoURL的完整内容
对应的属性内容可以在第4步进行设置数值
如果是video
将第2步创建的 video 对象添加到数组
5. 结束文档
所有内容解析完成,得到一个完整的数组
问题
1. 在那一个步骤,创建 video 对象比较合适
需要素材
1. 要有一个可变的数组,存放所有生成的video对象
2. 要一个可变的字符串,在第三步骤拼接字符串
3. 需要一个当前正在解析的video对象
在第2步创建
第3步拼接内容
第4步设置属性/添加到数组
示例程序
#import "ViewController.h"
#import "Video.h"
@interface ViewController ()<NSXMLParserDelegate>
/**整个xml的数据容器*/
@property(nonatomic,strong)NSMutableArray *videos;
/**第3步拼接字符串*/
@property(nonatomic,strong)NSMutableString *elementString;
/**当前的模型*/
@property(nonatomic,strong)Video *currentVideo;
/**表格的所有数据*/
@property (nonatomic,strong)
NSMutableArray *dataList;
@end
@implementation ViewController
- (void)setDataList:(NSMutableArray *)dataList
{
_dataList = dataList;
// 只要重新给表格的数据容器赋值,就刷新
[self.tableViewreloadData];
// 隐藏刷新控件
[self.refreshControlendRefreshing];
}
- (NSMutableArray *)videos
{
if (_videos ==nil) {
_videos = [NSMutableArrayarray];
}
return_videos;
}
- (NSMutableString *)elementString
{
if (_elementString ==nil) {
_elementString = [NSMutableStringstring];
}
return_elementString;
}
- (void)viewDidLoad {
[superviewDidLoad];
[selfloadData];
}
#pragma mark - 加载数据
- (IBAction)loadData
{
// 1. url
NSURL *url = [NSURLURLWithString:@"http://127.0.0.1/videos.xml"];
// 2. 请求
NSURLRequest *request = [NSURLRequestrequestWithURL:url
cachePolicy:1timeoutInterval:2.0f];
// 3. 连接
[NSURLConnectionsendAsynchronousRequest:request
queue:[NSOperationQueuemainQueue]
completionHandler:^(NSURLResponse *response,NSData *data,
NSError *connectionError) {
// xml的解析
// 1. 实例化一个xml的解析器--通过代理来实现xml的解析
NSXMLParser *parse = [[NSXMLParseralloc]
initWithData:data];
// 2. 设置代理
parse.delegate =self;
// 3. 解析器开始解析
[parse parse];
}];
}
#pragma mark - 代理方法
//1.打开文档,准备开始解析
- (void)parserDidStartDocument:(NSXMLParser *)parser
{
NSLog(@"1.打开文档,
准备开始解析");
// 初始化数组容器,清空容器,便于多次加载数据
[self.videosremoveAllObjects];
}
//2.开始节点
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString
*)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
NSLog(@"2.开始节点%@---%@", elementName, attributeDict);
// 如果开始节点的名称是video,就创建一个对象
if ([elementNameisEqualToString:@"video"]) {
self.currentVideo = [[Videoalloc]
init];
// 设置videoID
self.currentVideo.videoId = attributeDict[@"videoId"];
}
// 清空字符串的内容,因为马上要进入第3个方法,要开始拼接当前的节点的内容
[self.elementStringsetString:@""];
}
//3. 发现节点里面内容
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
NSLog(@"3.发现节点里面内容--->%@", string);
// 开始拼接
[self.elementStringappendString:string];
}
//4. 结束节点
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString
*)namespaceURI qualifiedName:(NSString *)qName
{
NSLog(@"4.结束节点 %@", elementName);
if ([elementNameisEqualToString:@"video"]) {
// 如果结束的节点是video,需要把这个对象添加到数组
[self.videosaddObject:self.currentVideo];
}elseif (![elementName
isEqualToString:@"videos"]){
[self.currentVideosetValue:self.elementStringforKeyPath:elementName];
}
// else if ([elementName isEqualToString:@"name"]) {//如果结束节点,就可以把第二步创建的对象,设置name/length属性
// // 设置name属性
// // 1. 直接赋值
//// self.currentVideo.name = self.elementString;
// // 2. KVC赋值
//// [self.currentVideo setValue:self.elementString forKeyPath:@"name"];
// // 3. 改造
// [self.currentVideo setValue:self.elementString forKeyPath:elementName];
// }else if ([elementName isEqualToString:@"length"]){
// // 设置length属性
//// self.currentVideo.length = @([self.elementString integerValue]);
//
// [self.currentVideo setValue:self.elementString forKeyPath:elementName];
// }else if ([elementName isEqualToString:@"videoURL"]){
// // 设置videoURL属性
//// self.currentVideo.videoURL = self.elementString;
// [self.currentVideo setValue:self.elementString forKeyPath:elementName];
// }else if ([elementName isEqualToString:@"desc"]){
// // 设置desc属性
//// self.currentVideo.desc = self.elementString;
// [self.currentVideo setValue:self.elementString forKeyPath:elementName];
// }else if ([elementName isEqualToString:@"teacher"]){
// // 设置teacher属性
//// self.currentVideo.teacher = self.elementString;
// [self.currentVideo setValue:self.elementString forKeyPath:elementName];
// }
// cocoa 的大招 KVC
}
//5 结束文档
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
NSLog(@"5结束文档");
// xml真正解析结束,可以更新UI,
在主线程
dispatch_async(dispatch_get_main_queue(), ^{
self.dataList =self.videos;
});
}
#pragma tabel数据源方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
returnself.videos.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath
*)indexPath
{
UITableViewCell *cell = [tableViewdequeueReusableCellWithIdentifier:@"cell"];
Video *video =self.dataList[indexPath.row];
cell.textLabel.text = video.name;
return cell;
}
@end
得到一个video的数组
包含很多个video对象
每一个video对象的内容是包含在video节点之间的
1. 开始文档
准备工作
2. 开始节点
新建一个 video 对象
可以设置 videoId 的属性
name
3. 发现节点文字
发现每一个节点的内容字符串
拼接字符串的工作
XML 解析的思路
目标
得到一个video的数组
包含很多个video对象
每一个video对象的内容是包含在video节点之间的
1. 开始文档
准备工作
2. 开始节点
新建一个 video 对象
可以设置 videoId 的属性
name
3. 发现节点文字
发现每一个节点的内容字符串
拼接字符串的工作
4. 结束节点
如果第2步是name
第3步拼接出来的字符串,就是要设置给name的完整内容
如果第2步是lenght
第3步拼接出来的字符串,就是要设置给length的完整内容
如果第2步是videoURL
第3步拼接出来的字符串,就是要设置给videoURL的完整内容
对应的属性内容可以在第4步进行设置数值
如果是video
将第2步创建的 video 对象添加到数组
5. 结束文档
所有内容解析完成,得到一个完整的数组
问题
1. 在那一个步骤,创建 video 对象比较合适
需要素材
1. 要有一个可变的数组,存放所有生成的video对象
2. 要一个可变的字符串,在第三步骤拼接字符串
3. 需要一个当前正在解析的video对象
在第2步创建
第3步拼接内容
第4步设置属性/添加到数组
4. 结束节点
如果第2步是name
第3步拼接出来的字符串,就是要设置给name的完整内容
如果第2步是lenght
第3步拼接出来的字符串,就是要设置给length的完整内容
如果第2步是videoURL
第3步拼接出来的字符串,就是要设置给videoURL的完整内容
对应的属性内容可以在第4步进行设置数值
如果是video
将第2步创建的 video 对象添加到数组
5. 结束文档
所有内容解析完成,得到一个完整的数组
问题
1. 在那一个步骤,创建 video 对象比较合适
需要素材
1. 要有一个可变的数组,存放所有生成的video对象
2. 要一个可变的字符串,在第三步骤拼接字符串
3. 需要一个当前正在解析的video对象
在第2步创建
第3步拼接内容
第4步设置属性/添加到数组
示例程序
#import "ViewController.h"
#import "Video.h"
@interface ViewController ()<NSXMLParserDelegate>
/**整个xml的数据容器*/
@property(nonatomic,strong)NSMutableArray *videos;
/**第3步拼接字符串*/
@property(nonatomic,strong)NSMutableString *elementString;
/**当前的模型*/
@property(nonatomic,strong)Video *currentVideo;
/**表格的所有数据*/
@property (nonatomic,strong)
NSMutableArray *dataList;
@end
@implementation ViewController
- (void)setDataList:(NSMutableArray *)dataList
{
_dataList = dataList;
// 只要重新给表格的数据容器赋值,就刷新
[self.tableViewreloadData];
// 隐藏刷新控件
[self.refreshControlendRefreshing];
}
- (NSMutableArray *)videos
{
if (_videos ==nil) {
_videos = [NSMutableArrayarray];
}
return_videos;
}
- (NSMutableString *)elementString
{
if (_elementString ==nil) {
_elementString = [NSMutableStringstring];
}
return_elementString;
}
- (void)viewDidLoad {
[superviewDidLoad];
[selfloadData];
}
#pragma mark - 加载数据
- (IBAction)loadData
{
// 1. url
NSURL *url = [NSURLURLWithString:@"http://127.0.0.1/videos.xml"];
// 2. 请求
NSURLRequest *request = [NSURLRequestrequestWithURL:url
cachePolicy:1timeoutInterval:2.0f];
// 3. 连接
[NSURLConnectionsendAsynchronousRequest:request
queue:[NSOperationQueuemainQueue]
completionHandler:^(NSURLResponse *response,NSData *data,
NSError *connectionError) {
// xml的解析
// 1. 实例化一个xml的解析器--通过代理来实现xml的解析
NSXMLParser *parse = [[NSXMLParseralloc]
initWithData:data];
// 2. 设置代理
parse.delegate =self;
// 3. 解析器开始解析
[parse parse];
}];
}
#pragma mark - 代理方法
//1.打开文档,准备开始解析
- (void)parserDidStartDocument:(NSXMLParser *)parser
{
NSLog(@"1.打开文档,
准备开始解析");
// 初始化数组容器,清空容器,便于多次加载数据
[self.videosremoveAllObjects];
}
//2.开始节点
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString
*)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
NSLog(@"2.开始节点%@---%@", elementName, attributeDict);
// 如果开始节点的名称是video,就创建一个对象
if ([elementNameisEqualToString:@"video"]) {
self.currentVideo = [[Videoalloc]
init];
// 设置videoID
self.currentVideo.videoId = attributeDict[@"videoId"];
}
// 清空字符串的内容,因为马上要进入第3个方法,要开始拼接当前的节点的内容
[self.elementStringsetString:@""];
}
//3. 发现节点里面内容
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
NSLog(@"3.发现节点里面内容--->%@", string);
// 开始拼接
[self.elementStringappendString:string];
}
//4. 结束节点
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString
*)namespaceURI qualifiedName:(NSString *)qName
{
NSLog(@"4.结束节点 %@", elementName);
if ([elementNameisEqualToString:@"video"]) {
// 如果结束的节点是video,需要把这个对象添加到数组
[self.videosaddObject:self.currentVideo];
}elseif (![elementName
isEqualToString:@"videos"]){
[self.currentVideosetValue:self.elementStringforKeyPath:elementName];
}
// else if ([elementName isEqualToString:@"name"]) {//如果结束节点,就可以把第二步创建的对象,设置name/length属性
// // 设置name属性
// // 1. 直接赋值
//// self.currentVideo.name = self.elementString;
// // 2. KVC赋值
//// [self.currentVideo setValue:self.elementString forKeyPath:@"name"];
// // 3. 改造
// [self.currentVideo setValue:self.elementString forKeyPath:elementName];
// }else if ([elementName isEqualToString:@"length"]){
// // 设置length属性
//// self.currentVideo.length = @([self.elementString integerValue]);
//
// [self.currentVideo setValue:self.elementString forKeyPath:elementName];
// }else if ([elementName isEqualToString:@"videoURL"]){
// // 设置videoURL属性
//// self.currentVideo.videoURL = self.elementString;
// [self.currentVideo setValue:self.elementString forKeyPath:elementName];
// }else if ([elementName isEqualToString:@"desc"]){
// // 设置desc属性
//// self.currentVideo.desc = self.elementString;
// [self.currentVideo setValue:self.elementString forKeyPath:elementName];
// }else if ([elementName isEqualToString:@"teacher"]){
// // 设置teacher属性
//// self.currentVideo.teacher = self.elementString;
// [self.currentVideo setValue:self.elementString forKeyPath:elementName];
// }
// cocoa 的大招 KVC
}
//5 结束文档
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
NSLog(@"5结束文档");
// xml真正解析结束,可以更新UI,
在主线程
dispatch_async(dispatch_get_main_queue(), ^{
self.dataList =self.videos;
});
}
#pragma tabel数据源方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
returnself.videos.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath
*)indexPath
{
UITableViewCell *cell = [tableViewdequeueReusableCellWithIdentifier:@"cell"];
Video *video =self.dataList[indexPath.row];
cell.textLabel.text = video.name;
return cell;
}
@end
相关文章推荐
- XML 与 JSON 优劣对比
- As3.0 xml + Loader应用代码
- DVI 视频接口图文解析
- IE6不能正常解析CSS文件问题的解决方法及原因分析
- 网马生成器 MS Internet Explorer XML Parsing Buffer Overflow Exploit (vista) 0day
- ext读取两种结构的xml的代码
- C#自写的一个HTML解析类(类似XElement语法)
- C#针对xml基本操作及保存配置文件应用实例
- ruby 过程对象 解析
- asp下查询xml的实现代码
- sqlserver FOR XML PATH 语句的应用
- 使用sp_xml_preparedocument处理XML文档的方法
- C#域名解析简单实现方法
- C#中的Linq to Xml详解
- C#操作XML文件实例汇总
- SQL Server中的XML数据进行insert、update、delete
- SQL Server中的XML数据进行insert、update、delete操作实现代码
- 关于SQLServer2005的学习笔记 XML的处理
- C#通过DataSet读写xml文件的方法