IOS开发-XML文件解析-NSXMLParser

使用的是苹果官方提供的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




你可能感兴趣的:(IOS开发-XML文件解析-NSXMLParser)