使用的是苹果官方提供的NSXMLParser类。
程序从服务器拿到xml文件。然后使用NSXMLParserDeleage的代理方法来解析文件。
先来看一下NSXMLParserDelegate的代理方法。
第一步,从服务器拿到xml文件,并初始化NSXMLParser解析器
#pragma mark --加载数据 - (void)loadData { //1.创建url NSURL * url = [NSURL URLWithString:@"http://127.0.0.1/videos.xml"]; //2.创建请求 NSURLRequest * request = [NSURLRequest requestWithURL:url cachePolicy:1 timeoutInterval:2.0]; //3.创建会话 NSURLSession * session = [NSURLSession sharedSession]; //4.创建任务 NSURLSessionTask * dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { //xml解析 //1.实例化一个xml的解析器--通过代理来实现xml的解析 NSXMLParser * parase = [[NSXMLParser alloc]initWithData:data]; //2.设置代理 parase.delegate = self; //3.解析器开始解析 [parase parse]; }]; //5.开始任务 [dataTask resume]; }
第二步:解析器开始解析的时候,会调用代理中的方法。代理中的方法如下
#pragma mark xml代理解析 //1.打开文档,准备解析文件 - (void)parserDidStartDocument:(NSXMLParser *)parser { NSLog(@"1.打开文档,准备开始解析"); } //2.开始节点 - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict { NSLog(@"2.开始节点解析"); } //3.发下节点里面的内容 - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { NSLog(@"3.发现节点里面的内容"); } //4.结束节点 - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { NSLog(@"4.结束节点"); } //5.结束文档 - (void)parserDidEndDocument:(NSXMLParser *)parser { NSLog(@"5.结束文档"); }
第三步:打印结果如下
2016-03-16 09:32:05.097 XML文件解析[14843:188675] 1.打开文档,准备开始解析 2016-03-16 09:32:05.098 XML文件解析[14843:188675] 2.开始节点解析 2016-03-16 09:32:05.098 XML文件解析[14843:188675] 2.开始节点解析 2016-03-16 09:32:05.098 XML文件解析[14843:188675] 2.开始节点解析 2016-03-16 09:32:05.098 XML文件解析[14843:188675] 3.发现节点里面的内容 2016-03-16 09:32:05.098 XML文件解析[14843:188675] 3.发现节点里面的内容 2016-03-16 09:32:05.099 XML文件解析[14843:188675] 4.结束节点 2016-03-16 09:32:05.205 XML文件解析[14843:188675] 2.开始节点解析 2016-03-16 09:32:05.205 XML文件解析[14843:188675] 3.发现节点里面的内容 2016-03-16 09:32:05.205 XML文件解析[14843:188675] 3.发现节点里面的内容 2016-03-16 09:32:05.206 XML文件解析[14843:188675] 4.结束节点 2016-03-16 09:32:05.206 XML文件解析[14843:188675] 2.开始节点解析 2016-03-16 09:32:05.206 XML文件解析[14843:188675] 3.发现节点里面的内容 2016-03-16 09:32:05.206 XML文件解析[14843:188675] 4.结束节点 2016-03-16 09:32:05.207 XML文件解析[14843:188675] 4.结束节点 2016-03-16 09:32:05.207 XML文件解析[14843:188675] 4.结束节点 2016-03-16 09:32:05.207 XML文件解析[14843:188675] 5.结束文档
上面就是简单的xml文件解析的流程。
下面对一个具体的xml文件进行解析:
<?xml version="1.0" encoding="utf-8"?> <videos> <video videoId="1"> <name>01.C语言-语法预览</name> <length>320</length> <videoURL>/itcast/videos/01.C语言-语法预览.mp4</videoURL> <imageURL>/itcast/images/head1.png</imageURL> <desc>C语言-语法预览</desc> <teacher>李明杰</teacher> </video> <video videoId="2"> <name>02.C语言-第一个C程序</name> <length>2708</length> <videoURL>/itcast/videos/02.C语言-第一个C程序.mp4</videoURL> <imageURL>/itcast/images/head2.png</imageURL> <desc>C语言-第一个C程序</desc> <teacher>李明杰</teacher> </video> </videos>
解析过程如下:
1.比如上面的xml文件,可以知道xml文件是由2个 video的item组成,每个video都有相同的标签。那么在解析的时候,可以把每个video看成一个对象。然后在解析完xml文件后,就可以把数据保存到两个对象里面。所以先定义video对应的对象类(Video类)。
.h文件 #import <Foundation/Foundation.h> @interface Video : NSObject @property (nonatomic, assign) NSInteger videoId; @property (nonatomic, copy) NSString *name; @property (nonatomic, assign) NSInteger length; @property (nonatomic, copy) NSString *videoURL; @property (nonatomic, copy) NSString *imageURL; @property (nonatomic, copy) NSString *desc; @property (nonatomic, copy) NSString *teacher; - (instancetype)initWithDict:(NSDictionary *)dict; + (instancetype)videoWithDict:(NSDictionary *)dict; @end .m文件 #import "Video.h" @implementation Video - (instancetype)initWithDict:(NSDictionary *)dict { self = [super init]; if (self) { [self setValuesForKeysWithDictionary:dict]; } return self; } + (instancetype)videoWithDict:(NSDictionary *)dict { return [[self alloc] initWithDict:dict]; } - (NSString *)description { return [NSString stringWithFormat:@"\n { \nvideoId : %ld\n name : %@ \n length : %ld \n videoURL : %@ \n imageURL : %@ \n desc : %@ \n teacher : %@\n}", self.videoId, self.name, self.length, self.videoURL, self.imageURL, self.desc, self.teacher]; } @end
2.创建整个xml文件对应的对象的数组,在解析结束后,把解析出来的对象保存到这个数组中
/*整个aml的数据容器*/ @property (nonatomic,strong)NSMutableArray * videos;
3.创建一个Video对象,用来保存正在解析的xml的一个item对应的对象
/*当前的模型*/ @property (nonatomic,strong)Video * currentVideo;
4.在解析xml的时候,解析一个节点时可能需要多次调用foundCharacters才把一个节点的数据解析完成,所以需要一个可变的字符串,在解析的时候,保存节点的数据。
/*第3步 拼接字符串*/ @property (nonatomic,strong)NSMutableString * elementString;
5.解析的步骤代码:
#pragma mark xml代理解析 //1.打开文档,准备解析文件 - (void)parserDidStartDocument:(NSXMLParser *)parser { NSLog(@"1.打开文档,准备开始解析"); [self.videos removeAllObjects]; } //2.开始节点 - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict { NSLog(@"2.开始节点解析----节点:%@",elementName); if ([elementName isEqualToString:@"video"]) { self.currentVideo = [[Video alloc]init]; //设置videoId self.currentVideo.videoId = [attributeDict[@"videoId"] integerValue]; } //清空上次节点解析时保存的数据 [self.elementString setString:@""]; } //3.发现节点里面的内容 - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { NSLog(@"3.发现节点里面的内容"); [self.elementString appendString:string]; } //4.结束节点 - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { NSLog(@"4.结束节点的解析---%@",elementName); if ([elementName isEqualToString:@"video"]) { //如果结束的节点是video,需要把这个对象添加到数组 [self.videos addObject:self.currentVideo]; } else if(![elementName isEqualToString:@"videos"]) { [self.currentVideo setValue:self.elementString forKey:elementName]; } } //5.结束文档 - (void)parserDidEndDocument:(NSXMLParser *)parser { NSLog(@"5.结束文档"); NSLog(@"self.videos.count = %ld",self.videos.count); for (Video * video in self.videos) { NSLog(@"--video %@",video); } }
5.打印结果如下:
2016-03-16 12:01:42.722 XML文件解析[24379:338409] 1.打开文档,准备开始解析 2016-03-16 12:01:42.722 XML文件解析[24379:338409] 2.开始节点解析----节点:videos 2016-03-16 12:01:42.723 XML文件解析[24379:338409] 3.发现节点里面的内容 2016-03-16 12:01:42.723 XML文件解析[24379:338409] 2.开始节点解析----节点:video 2016-03-16 12:01:42.724 XML文件解析[24379:338409] 3.发现节点里面的内容 2016-03-16 12:01:42.724 XML文件解析[24379:338409] 2.开始节点解析----节点:name 2016-03-16 12:01:42.725 XML文件解析[24379:338409] 3.发现节点里面的内容 2016-03-16 12:01:42.725 XML文件解析[24379:338409] 3.发现节点里面的内容 2016-03-16 12:01:42.725 XML文件解析[24379:338409] 4.结束节点 name 的解析 2016-03-16 12:01:42.726 XML文件解析[24379:338409] 3.发现节点里面的内容 2016-03-16 12:01:42.726 XML文件解析[24379:338409] 2.开始节点解析----节点:length 2016-03-16 12:01:42.727 XML文件解析[24379:338409] 3.发现节点里面的内容 2016-03-16 12:01:42.727 XML文件解析[24379:338409] 4.结束节点 length 的解析 2016-03-16 12:01:42.728 XML文件解析[24379:338409] 3.发现节点里面的内容 2016-03-16 12:01:42.728 XML文件解析[24379:338409] 2.开始节点解析----节点:videoURL 2016-03-16 12:01:42.729 XML文件解析[24379:338409] 3.发现节点里面的内容 2016-03-16 12:01:42.729 XML文件解析[24379:338409] 3.发现节点里面的内容 2016-03-16 12:01:42.729 XML文件解析[24379:338409] 4.结束节点 videoURL 的解析 2016-03-16 12:01:42.729 XML文件解析[24379:338409] 3.发现节点里面的内容 2016-03-16 12:01:42.730 XML文件解析[24379:338409] 2.开始节点解析----节点:imageURL 2016-03-16 12:01:42.731 XML文件解析[24379:338409] 3.发现节点里面的内容 2016-03-16 12:01:42.731 XML文件解析[24379:338409] 4.结束节点 imageURL 的解析 2016-03-16 12:01:42.733 XML文件解析[24379:338409] 3.发现节点里面的内容 2016-03-16 12:01:42.734 XML文件解析[24379:338409] 2.开始节点解析----节点:desc 2016-03-16 12:01:42.734 XML文件解析[24379:338409] 3.发现节点里面的内容 2016-03-16 12:01:42.735 XML文件解析[24379:338409] 3.发现节点里面的内容 2016-03-16 12:01:42.736 XML文件解析[24379:338409] 4.结束节点 desc 的解析 2016-03-16 12:01:42.736 XML文件解析[24379:338409] 3.发现节点里面的内容 2016-03-16 12:01:42.737 XML文件解析[24379:338409] 2.开始节点解析----节点:teacher 2016-03-16 12:01:42.737 XML文件解析[24379:338409] 3.发现节点里面的内容 2016-03-16 12:01:42.738 XML文件解析[24379:338409] 4.结束节点 teacher 的解析 2016-03-16 12:01:42.738 XML文件解析[24379:338409] 3.发现节点里面的内容 2016-03-16 12:01:42.738 XML文件解析[24379:338409] 4.结束节点 video 的解析 2016-03-16 12:01:42.739 XML文件解析[24379:338409] 3.发现节点里面的内容 2016-03-16 12:01:42.739 XML文件解析[24379:338409] 2.开始节点解析----节点:video 2016-03-16 12:01:42.740 XML文件解析[24379:338409] 3.发现节点里面的内容 2016-03-16 12:01:42.740 XML文件解析[24379:338409] 2.开始节点解析----节点:name 2016-03-16 12:01:42.741 XML文件解析[24379:338409] 3.发现节点里面的内容 2016-03-16 12:01:42.741 XML文件解析[24379:338409] 3.发现节点里面的内容 2016-03-16 12:01:42.742 XML文件解析[24379:338409] 4.结束节点 name 的解析 2016-03-16 12:01:42.742 XML文件解析[24379:338409] 3.发现节点里面的内容 2016-03-16 12:01:42.743 XML文件解析[24379:338409] 2.开始节点解析----节点:length 2016-03-16 12:01:42.743 XML文件解析[24379:338409] 3.发现节点里面的内容 2016-03-16 12:01:42.743 XML文件解析[24379:338409] 4.结束节点 length 的解析 2016-03-16 12:01:42.744 XML文件解析[24379:338409] 3.发现节点里面的内容 2016-03-16 12:01:42.744 XML文件解析[24379:338409] 2.开始节点解析----节点:videoURL 2016-03-16 12:01:42.744 XML文件解析[24379:338409] 3.发现节点里面的内容 2016-03-16 12:01:42.745 XML文件解析[24379:338409] 3.发现节点里面的内容 2016-03-16 12:01:42.746 XML文件解析[24379:338409] 4.结束节点 videoURL 的解析 2016-03-16 12:01:42.746 XML文件解析[24379:338409] 3.发现节点里面的内容 2016-03-16 12:01:42.746 XML文件解析[24379:338409] 2.开始节点解析----节点:imageURL 2016-03-16 12:01:42.748 XML文件解析[24379:338409] 3.发现节点里面的内容 2016-03-16 12:01:42.748 XML文件解析[24379:338409] 4.结束节点 imageURL 的解析 2016-03-16 12:01:42.749 XML文件解析[24379:338409] 3.发现节点里面的内容 2016-03-16 12:01:42.749 XML文件解析[24379:338409] 2.开始节点解析----节点:desc 2016-03-16 12:01:42.750 XML文件解析[24379:338409] 3.发现节点里面的内容 2016-03-16 12:01:42.750 XML文件解析[24379:338409] 3.发现节点里面的内容 2016-03-16 12:01:42.751 XML文件解析[24379:338409] 4.结束节点 desc 的解析 2016-03-16 12:01:42.752 XML文件解析[24379:338409] 3.发现节点里面的内容 2016-03-16 12:01:42.753 XML文件解析[24379:338409] 2.开始节点解析----节点:teacher 2016-03-16 12:01:42.754 XML文件解析[24379:338409] 3.发现节点里面的内容 2016-03-16 12:01:42.754 XML文件解析[24379:338409] 4.结束节点 teacher 的解析 2016-03-16 12:01:42.755 XML文件解析[24379:338409] 3.发现节点里面的内容 2016-03-16 12:01:42.755 XML文件解析[24379:338409] 4.结束节点 video 的解析 2016-03-16 12:01:42.756 XML文件解析[24379:338409] 3.发现节点里面的内容 2016-03-16 12:01:42.756 XML文件解析[24379:338409] 4.结束节点 videos 的解析 2016-03-16 12:01:42.757 XML文件解析[24379:338409] 5.结束文档 2016-03-16 12:01:42.757 XML文件解析[24379:338409] self.videos.count = 2 2016-03-16 12:01:42.758 XML文件解析[24379:338409] --video { videoId : 1 name : 01.C语言-语法预览 length : 320 videoURL : /itcast/videos/01.C语言-语法预览.mp4 imageURL : /itcast/images/head1.png desc : C语言-语法预览 teacher : 李明杰 } 2016-03-16 12:01:42.758 XML文件解析[24379:338409] --video { videoId : 2 name : 02.C语言-第一个C程序 length : 2708 videoURL : /itcast/videos/02.C语言-第一个C程序.mp4 imageURL : /itcast/images/head2.png desc : C语言-第一个C程序 teacher : 李明杰 }
Demo代码:http://www.oschina.net/code/snippet_2290420_54745