您的位置:首页 > 其它

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  xml 解析