用NSXMLParser解析XML文件过程:
1 创建NSXMLParser实例,并传入从服务器接收XML数据。
2 定义解析器代理
3 解析器解析。
4 通过解析代理方法完成XML数据的解析。
#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];
//1实例化解析器,传入要解析的数据
NSXMLParser *parser = [[NSXMLParser alloc]initWithData:data];
//2 设置代理
[parser setDelegate:self];
//3解析器解析,这个方法会调用代理里面的方法。
[parser parse];
}
/*
xml解析思路;
0 数据初始化工作,实例化dataList和第三步需要使用的全局字符串。
1 如果在第二个方法中,elementName == video .会在attributeDict中包含videoId
2 如果在第二个方法中, elementName == video。。需要实例化一个全局的video属性,记录2 3 4步骤中解析当前视频信息对象
3 其它的属性会依次执行2 ,3 ,4 方法,同时在第三个方法中可能多次被调用。
4 在第三个方法中,需要拼接字符串 需要定义一个全局的属性记录中间过程
5 在第四个方法中,可以通过第三个方法拼接出的字符串获得elementName对应的内容。
可以设置全局video对象的elementName对应的数值。
6 在第四个方法中,如果elementName == video,则将该方法插入datalist中。
需要的准备工作:
1 全局的字符串,记录每一个元素的完整内容。
2 全局的video对象,记录当前正在解析的元素。
*/
#pragma mark - XML解析器代理方法
//1 解析文档
- (void)parserDidStartDocument:(NSXMLParser *)parser
{
NSLog(@"开始解析");
//懒加载实例化数据
if (self.dataList == nil) {
self.dataList = [NSMutableArray array];
}else{
[self.dataList removeAllObjects];
}
//中间字符串
if(self.elementString == nil)
{
self.elementString = [NSMutableString string];
}else{
//self.elementString = @"";
[self.elementString setString:@""];
}
}
//在整个XML文件解析完成之前, 2,3,4会被重复调用
//2开始解析一个元素,新的节点开始了。
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
NSLog(@"开始解析元素 %@ %@", elementName, attributeDict);
if ([elementName isEqualToString:@"video"]) {
//1 实例化currentvideo
self.currentVideo = [[Video alloc]init];
//2 保存videoid
self.currentVideo.videoId = [attributeDict[@"videoId"]integerValue];
}
//需要清空中转字符串
[self.elementString setString:@""];
}
//3接收元素的数据(发现字符,这个方法会因为元素内容过大,此方法会被重复调用,需要拼接数据)
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
NSLog(@"发现字符 %@", string);
[self.elementString appendString:string];
}
//4结束解析一个元素
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
NSLog(@"完成解析元素 %@", elementName);
//获得第三步拼接出来的字符串。
NSString *result = [NSString stringWithString:self.elementString];
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];
}
}
//5解析文档结束
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
NSLog(@"文档结束 %@", self.dataList);
//清空临时数据
self.currentVideo = nil;
[self.elementString setString:@""];
//uitableview刷新数据
[self.tableView reloadData];
}
//6解析出错
- (void)parser:(NSXMLParser *)parser validationErrorOccurred:(NSError *)validationError
{
NSLog(@"解析出现错误");
//清空临时数据
self.currentVideo = nil;
[self.elementString setString:@""];
//清空临时数组
[self.dataList removeAllObjects];
}