XML解析
2017-02-08 本文已影响17人
952625a28d0d
#import "ViewController.h"
#import "Video.h"
@interface ViewController ()<NSXMLParserDelegate>
// MARK: -XML解析需要的素材
// 可变数组
@property (nonatomic,strong) NSMutableArray *videos;
// 当前解析的节点 -- 模型
@property (nonatomic, strong) Video *currentVideo;
// 拼接我们的字符串 -- 可变字符串
@property (nonatomic, copy) NSMutableString *elementStr;
@end
@implementation ViewController
- (NSMutableArray *)videos{
if (!_videos) {
_videos = [NSMutableArray array];
}
return _videos;
}
- (NSMutableString *)elementStr{
if (!_elementStr) {
_elementStr = [[NSMutableString alloc] init];
}
return _elementStr;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self loadData];
}
- (void)loadData{
NSURL *url = [NSURL URLWithString:@""];
NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:1 timeoutInterval:10.0];
[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
// XML解析 -- 耗时操作
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
// 设置代理 - 一旦解析器开始解析 都是通过代理来监听实现的
parser.delegate = self;
// 解析XML 解析器解析
[parser parse];
}];
}
#pragma mark - XML解析的代理方法
/**
目标:解析成为一个包含多个Video的数组
*/
// 1.打开文档
- (void)parserDidStartDocument:(NSXMLParser *)parser{
// 清空我们的数组
[self.videos removeAllObjects];
}
// 2.开始节点
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict{
NSLog(@"开始节点%@",elementName);
// 判断是不是Video 如果是Video 创建Video对象
if ([elementName isEqualToString:@"video"]) {
// 新建video对象
self.currentVideo = [[Video alloc] init];
// 设置VideoId属性 用对象包装一下
self.currentVideo.videoId = @([attributeDict[@"videoId"] intValue]);
}
}
// 3.发现节点内容(一个节点可能会读取很多次) string 就是内容
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
// 拼接字符串
NSLog(@"发现节点内容%@",string);
[self.elementStr appendString:string];
}
// 4.结束节点
/**
KVC key value coding 键值编码 间接的设置值得方式
cocoa 的一个大招
*/
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
NSLog(@"结束节点名称%@",elementName);
// 如果是name length imageUrl desc video
if ([elementName isEqualToString:@"video"]) {
// 如果是video 添加模型到数组
[self.videos addObject:self.currentVideo];
}else if (![elementName isEqualToString:@"videos"]){
[self.currentVideo setValue:self.elementStr forKey:elementName];
}
// 清空字符串
[self.elementStr setString:@""];
}
// 5.结束文档
- (void)parserDidEndDocument:(NSXMLParser *)parser{
NSLog(@"结束文档");
}
// 6.如果出现了错误(只要是网络开发,就需要处理错误)
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError{
NSLog(@"发生错误%@",parseError);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
#import <Foundation/Foundation.h>
@interface Person : NSObject
// id 还是能用的 为了好看 用大写ID也是可以的
@property (nonatomic, strong) NSNumber *ID;
// kvc字符串判空
@property (nonatomic, copy) NSString *name;
// 技巧 这里使用NSNumber 而不使用基本数据类型 可以避免服务器返回null的时候崩溃
@property (nonatomic, strong) NSNumber *age;
@end