自己写了一个比较乱的sample,用于应对各种坑爹后台的解析,xml文件如上图节点下面有字段,有数组,数组再套嵌。
<channelprglistResult> <item> <id>1</id> <title>CCTV-1</title> <channelinfo_img> http://192.168.137.222/iepg/sites/default/files/styles/4/public/images/3/channel/CCTV1.png </channelinfo_img> <epglist> <item> <id>438740</id> <title>新闻30分</title> <channel_tm_begin>2012-06-06 12:00:00</channel_tm_begin> <channel_play>CCTV-1</channel_play> <channel_tm_end>2012-06-06 12:35:00</channel_tm_end> <channel_play_id>1</channel_play_id> </item> <item> <id>438741</id> <title>今日说法</title> <channel_tm_begin>2012-06-06 12:35:00</channel_tm_begin> <channel_play>CCTV-1</channel_play> <channel_tm_end>2012-06-06 13:13:00</channel_tm_end> <channel_play_id>1</channel_play_id> </item> <total>4</total> </epglist> </item> <item> <id>2</id> <title>CCTV-2</title> <channelinfo_img> http://192.168.137.222/iepg/sites/default/files/styles/4/public/images/3/channel/CCTV2.png </channelinfo_img> <epglist> <item> <id>438049</id> <title>环球财经连线</title> <channel_tm_begin>2012-06-06 11:50:00</channel_tm_begin> <channel_play>CCTV-2</channel_play> <channel_tm_end>2012-06-06 12:30:00</channel_tm_end> <channel_play_id>2</channel_play_id> </item> <item> <id>456292</id> <title>周末特供</title> <channel_tm_begin>2012-06-06 12:30:00</channel_tm_begin> <channel_play>CCTV-2</channel_play> <channel_tm_end>2012-06-06 13:29:00</channel_tm_end> <channel_play_id>2</channel_play_id> </item> <total>3</total> </epglist> </item> </channelprglistResult>
代码如下:
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;//标记起始tag 14 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 *)qName 109 { 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 }