#pragma mark 加载xml - (void)loadXML { //获取网络数据。 NSLog(@"load xml"); //从web服务器加载数据 NSString *str = @"http://www.baidu.com?format=xml"; //这里是乱写的 //1简历NSURL NSURL *url = [NSURL URLWithString:str]; //2建立NSURLRequest NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:2.0f]; //3建立NSURLConnect的同步方法加载数据 NSURLResponse *response = nil; NSError *error = nil; //同步加载数据 NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; MyXMLParser *myParser = [[MyXMLParser alloc]init]; //懒加载实例化数据 if (self.dataList == nil) { self.dataList = [NSMutableArray array]; }else{ [self.dataList removeAllObjects]; } //解析数据 [myParser xmlParserWithData:data StartName:@"video" startElement:^( NSDictionary *dict) { //1 实例化currentvideo self.currentVideo = [[Video alloc]init]; //2 设置videoid self.currentVideo.videoId = [dict[@"videoId"]integerValue]; } endElement:^(NSString *elementName, NSString *result) { if ([elementName isEqualToString:@"name"]) { self.currentVideo.name = result; }else if ([elementName isEqualToString:@"length"]){ self.currentVideo.length = [result integerValue]; }else if ([elementName isEqualToString:@"videoURL"]){ self.currentVideo.videoId = [result integerValue]; }else if ([elementName isEqualToString:@"imageURL"]){ self.currentVideo.imageURL = result; }else if ([elementName isEqualToString:@"desc"]){ self.currentVideo.desc = result; }else if ([elementName isEqualToString:@"teacher"]){ self.currentVideo.teacher = result; }else if ([elementName isEqualToString:@"video"]){ [self.dataList addObject:self.currentVideo]; } } finishedParser:^{ self.currentVideo = nil; [self.tableView reloadData]; //刷新表格数据 } errorParser:^{ NSLog(@"解析出现错误"); //清空临时数据 self.currentVideo = nil; //清空数组 [self.dataList removeAllObjects]; }]; }
<pre name="code" class="objc">#import <Foundation/Foundation.h> //代理方法中需要与调用者交互的方法: // 2 交互元素: elementname attributeDict // 4 交互的元素: elementname 中转的字符串 //5 仅通知即可 //6 仅通知即可 //定义块代码: typedef void(^startElementBlock)(NSDictionary *dict); typedef void(^endElementBlock)(NSString *elementName, NSString *result); typedef void(^xmlParserNotificationBlock)(); @interface MyXMLParser : NSObject //定义解析方法 /* data xml数据 startname 开始的节点名称 startElement 开始节点方法 endElement 结束节点方法 finishedparser 文档解析结束。 errorParse 文档解析出错。 */ -(void)xmlParserWithData:(NSData *)data StartName:(NSString *)startName startElement:(startElementBlock)startElement endElement:(endElementBlock)endElement finishedParser:(xmlParserNotificationBlock)finishedParser errorParser:(xmlParserNotificationBlock)errorParser; @end
<pre name="code" class="objc">#import "MyXMLParser.h" @interface MyXMLParser() <NSXMLParserDelegate> { //记录块代码的成员变量 startElementBlock _startElementBlock; endElementBlock _endElementBlock; xmlParserNotificationBlock _finishedBlock; xmlParserNotificationBlock _errorBlock; } //开始节点名称,列如:video 如果检测到此名称, 需要实例化对象 @property (strong, nonatomic)NSString *startElementName; //中转字符串 @property (strong, nonatomic) NSMutableString *elementString; @end @implementation MyXMLParser //在这个方法里面实现xml的解析。 /* data xml数据 startname 开始的节点名称 startElement 开始节点方法 endElement 结束节点方法 finishedparser 文档解析结束。 errorParse 文档解析出错。 */ - (void)xmlParserWithData:(NSData *)data StartName:(NSString *)startName startElement:(startElementBlock)startElement endElement:(endElementBlock)endElement finishedParser:(xmlParserNotificationBlock)finishedParser errorParser:(xmlParserNotificationBlock)errorParser { self.startElementName = startName; //记录块代码 _startElementBlock = startElement; _endElementBlock = endElement; _finishedBlock = finishedParser; _errorBlock = errorParser; //定义解析器并且开始解析 NSXMLParser *parser = [[NSXMLParser alloc]initWithData:data]; [parser setDelegate:self]; //设置代理 //开始解析 [parser parse]; //这个方法会调用下面的几个方法来实现。 } #pragma mark - XML解析器代理方法 //所谓需要与外界交互,表示需要与调用发打交道,通知调用放执行某些操作。 //1开始解析文档,初始化数据,也不需要与外部交互。 - (void)parserDidStartDocument:(NSXMLParser *)parser { //实例化中装字符串 if (self.elementString == nil) { self.elementString = [NSMutableString string]; } } //2开始解析元素(元素的头部video, 需要实例化对象, attributedict需要设置属性) //需要与外部交互 //交互的元素: elementName attributeDict - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict { if ([elementName isEqualToString:self.startElementName]) { //开始部分代码 _startElementBlock(attributeDict); } //开始循环执行第三个方法前,清空中转字符串 [self.elementString setString:@""]; } //3发现元素字符串(拼接字符串,不需要和外部交互) - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { [self.elementString appendString:string]; } //4结束元素解析,根据elementname和第三步的拼接内容,确定对象属性,需要与外部交互 //交互的元素: elementname 中转的字符串 - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { NSString *result = [NSString stringWithString:self.elementString]; _endElementBlock(elementName, result); } //5解析文档结束,通常需要调用放刷新数据。 //交互的元素: 仅通知即可 - (void)parserDidEndDocument:(NSXMLParser *)parser { [self.elementString setString:@""]; _finishedBlock(); } //解析出错,通知调用方解析出错(需要与外界交互)。 //交互的元素: 仅通知即可。 - (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError { NSLog(@"解析出错"); [self.elementString setString:@""]; //带一个nserror回去会更好。 _errorBlock(); } @end
ios网络学习------8 xml格式数据的请求处理 用代码块封装,布布扣,bubuko.com
时间: 2024-11-08 13:53:25