自己写了一个比较乱的sample,用于应对各种坑爹后台的解析,xml文件如上图节点下面有字段,有数组,数组再套嵌。
View Code
1 CCTV-1 http://192.168.137.222/iepg/sites/default/files/styles/4/public/images/3/channel/CCTV1.png 438740 新闻30分 2012-06-06 12:00:00 CCTV-1 2012-06-06 12:35:00 1 438741 今日说法 2012-06-06 12:35:00 CCTV-1 2012-06-06 13:13:00 1 4 2 CCTV-2 http://192.168.137.222/iepg/sites/default/files/styles/4/public/images/3/channel/CCTV2.png 438049 环球财经连线 2012-06-06 11:50:00 CCTV-2 2012-06-06 12:30:00 2 456292 周末特供 2012-06-06 12:30:00 CCTV-2 2012-06-06 13:29:00 2 3
代码如下:
1 //一个方法,包含读取本地文件转化成data,然后开始调用NSXMLParser,(需要把这个方法放入任意触发器中)。 2 -(void)getXMLResourceAndStartToParse{ 3 NSString *path = [[NSBundle mainBundle]pathForResource:@"jibada" ofType:@"xml"]; 4 NSFileHandle *file = [NSFileHandle fileHandleForReadingAtPath:path]; 5 NSData *data = [file readDataToEndOfFile]; 6 NSXMLParser *parser = [[NSXMLParser alloc]initWithData:data]; 7 [parser setDelegate:self]; 8 [parser parse]; 9 }10 11 12 -(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{13 storedAllKeys =YES;//标记起始tag14 keyName = elementName;15 if ([elementName isEqualToString:@"epglist"]) {16 epglistMark = YES;//epglist的起始标记17 }18 }19 20 -(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{21 if (storedAllKeys) {22 23 //在epglist标记之中24 if (epglistMark) {25 if ([keyName isEqualToString:@"title"]) {26 NSLog(@"Program name:%@",string);27 }else if ([keyName isEqualToString:@"channel_tm_begin"]) {28 NSLog(@"Begin time:%@",string);29 }30 }else if (!epglistMark) {31 if ([keyName isEqualToString:@"title"]) {32 NSLog(@"Channel name:%@",string);33 }34 }if ([keyName isEqualToString:@"channelinfo_img"]) {35 NSLog(@"%@",string);36 }37 }38 }39 40 -(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{41 storedAllKeys = NO;//结束标记42 if ([elementName isEqualToString:@"epglist"]) {43 epglistMark = NO;//epglist结束标记44 }45 }
didStartElement 方法是开始读取节点
foundCharacters 方法是查找相关字段
didEndElement 方法是是结束读取节点
NSXMLParser 代理主要的就是这三个方法,循环解析,如果用NSLog的方式输出 didStartElement 的 elementName参数 或 foundCharacters方法中的string参数
可以清晰看出输出的各节点,以及节点数组里面包含的各字段。
拿<channelprglistResult>...</channelprglistResult>举例说明
didStartElement 方法读取<channelprglistResult>节点,然后foundCharacters找到中间的关键字,最后didEndElement结束,因为这个节点下还包含了子节点没有关键字,所以NSLog形式输出会为空。
一般我们可以声明一个BOOL值来用YES标记didStartElement方法开始,BOOL值NO标记方法didEndElement结束,然后在BOOL开始和结束之间来查找我们需要的关键字,如上面代码。
以下是完整版,可以解析出每个字段。
1 //创建六个数组 2 //channnelNameArray 里面包含频道名称,共一个字段 3 //channnelImgURLArray 包含频道logo的URL地址,总一个字段 4 //firstProgramNameArray 包含第一个节目名称 一个字段 5 //secondProgramNameArray 包含第二个节目名称 一个字段 6 //firstBeginTimeArray 包含第一节目时间 一个字段 7 //secondBeginTimeArray 包含第二个节目时间 一个字段 8 9 //============================================================================================================================ 10 // 解析开始 11 //============================================================================================================================ 12 13 14 -(void)parserDidStartDocument:(NSXMLParser *)parser{ 15 self.channnelNameArray = [NSMutableArray new]; 16 self.firstProgramNameArray = [NSMutableArray new]; 17 self.secondProgramNameArray = [NSMutableArray new]; 18 self.firstBeginTimeArray = [NSMutableArray new]; 19 self.secondBeginTimeArray = [NSMutableArray new]; 20 self.channnelImgURLArray = [NSMutableArray new]; 21 itemCount = 0; 22 firstItemMark =NO; 23 secondeItemMark = NO; 24 25 } 26 27 28 -(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict 29 { 30 if (itemCount ==0) { 31 if ([elementName isEqualToString:@"item"]) { 32 itemCount=itemCount+1; 33 firstItemMark = YES; 34 } 35 }else if (itemCount ==1) { 36 if ([elementName isEqualToString:@"item"]) { 37 if (firstItemMark) { 38 itemCount=itemCount+1; 39 secondeItemMark = YES; 40 } 41 } 42 }else if (itemCount ==2) { 43 if ([elementName isEqualToString:@"item"]) { 44 if (firstItemMark) { 45 itemCount=itemCount+1; 46 secondeItemMark = YES; 47 } 48 } 49 } 50 if ([elementName isEqualToString:@"title"]) { 51 titleMark = YES; 52 } 53 if ([elementName isEqualToString:@"channel_tm_begin"]) { 54 channel_tm_beginMark = YES; 55 } 56 storedAllKeys =YES;//标记起始tag 57 keyName = elementName; 58 59 if ([elementName isEqualToString:@"epglist"]) 60 { 61 epglistMark = YES;//epglist的起始标记 62 63 } 64 } 65 66 -(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string 67 { 68 if (secondeItemMark) { 69 if (itemCount == 2) { 70 if ([keyName isEqualToString:@"title"]&&titleMark) { 71 // NSLog(@"firstProgramName:%@",string); 72 [self.firstProgramNameArray addObject:string]; 73 }else if ([keyName isEqualToString:@"channel_tm_begin"]&&channel_tm_beginMark) { 74 // NSLog(@"firstProgramName:%@",string); 75 [self.firstBeginTimeArray addObject:string]; 76 } 77 }else if (itemCount==3) { 78 if ([keyName isEqualToString:@"title"]&&titleMark) { 79 // NSLog(@"secondProgramName:%@",string); 80 [self.secondProgramNameArray addObject:string]; 81 }else if ([keyName isEqualToString:@"channel_tm_begin"]&&channel_tm_beginMark) { 82 // NSLog(@"secondProgramName:%@",string); 83 [self.secondBeginTimeArray addObject:string]; 84 } 85 } 86 } 87 88 if (storedAllKeys) 89 { 90 //在epglist标记之中 91 92 if (!epglistMark) 93 { 94 if ([keyName isEqualToString:@"title"]) 95 { 96 // NSLog(@"Channel name:%@",string); 97 [self.channnelNameArray addObject:string]; 98 } 99 }100 if ([keyName isEqualToString:@"channelinfo_img"]) 101 {102 // NSLog(@"channelImgURLArray:%@",string);103 [self.channnelImgURLArray addObject:string];104 }105 }106 }107 108 -(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName109 {110 storedAllKeys = NO;//结束标记111 if ([elementName isEqualToString:@"epglist"]) 112 {113 epglistMark = NO;//epglist结束标记114 115 }116 if ([elementName isEqualToString:@"title"]) {117 titleMark = NO;118 }119 if ([elementName isEqualToString:@"channel_tm_begin"]) {120 channel_tm_beginMark = NO;121 }122 if (itemCount ==2) {123 if (secondeItemMark) 124 {125 if ([elementName isEqualToString:@"item"]) 126 {127 secondeItemMark = NO;128 }129 }130 } 131 if (itemCount ==3) 132 {133 if (secondeItemMark) {134 if ([elementName isEqualToString:@"item"]) {135 secondeItemMark = NO;136 }137 }else {138 itemCount =0;139 firstItemMark = NO;140 }141 }142 }143 -(void)parserDidEndDocument:(NSXMLParser *)parser{144 [self.tableView reloadData];145 }