欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

iOS网络开发教程之XML解析

程序员文章站 2022-06-16 12:27:48
XML简介 什么是XML? 全称是 ExtensibleMarkupLanguage. 可扩展标记语言. 跟JSON一样,也是常用的一种用于交互的数据格式 一般也叫做XML...

XML简介

什么是XML?

全称是 ExtensibleMarkupLanguage. 可扩展标记语言.

跟JSON一样,也是常用的一种用于交互的数据格式

一般也叫做XML文档 ( XML Document )

XML举例
 
XML语法:

一个常见的XML文档一般由以下部分组成

文档声明

元素 ( Element )

一个元素包括了开始标签和结束标签
拥有内容的元素:
<video>
	小黄人</video>
没有内容的元素:
<video>
	&nbsp;</video>
没有内容的元素简写:
<video>
	一个元素可以嵌套若干个子元素(不能出现交叉嵌套) <videos>
	<video>
		<name>小黄人 第01部</name> <length>30</length></video>
	</videos> 规范的XML文档最多只有1个根元素,其他元素都是根元素的子孙元素</video>

属性 ( Attribute )

<video length="30" name="小黄人 第01部">
	video元素拥有name和length两个属性 属性值必须用 双引号&quot;&quot; 或者 单引号&#39;&#39; 括住 实际上,属性表示的信息也可以用子元素来表示,比如
	<video>
		<name>小黄人 第01部</name> <length>30</length></video>
</video>
 XML解析

XML的解析方式有2种

DOM: 一次性将整个XML文档加载进内存,比较适合解析小文件SAX: 从根元素开始,按顺序一个元素一个元素往下解析,比较适合 解析大文件

iOS网络开发教程之XML解析

SAX解析:( NSXMLParser )

#import "ViewController.h"
#import "UIImageView+WebCache.h"
#import 
#import "ZYVideo.h"
#import "MJExtension.h"

#define baseUrlStr @"https://120.25.226.186:32812"

@interface ViewController ()
/* 存储模型的 数组 */
@property (nonatomic, strong) NSMutableArray *videos;

@end

@implementation ViewController

- (NSMutableArray *)videos
{
    if (!_videos) {
        _videos = [NSMutableArray array];
    }
    return _videos;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 替换 模型中属性的名称 和 系统关键字冲突.(系统自带方法冲突)
    [ZYVideo mj_setupReplacedKeyFromPropertyName:^NSDictionary *{
        return @{
                 @"ID" : @"id"
                 };
    }];
    
    //1. 确定url
    NSURL *url = [NSURL URLWithString:@"https://localhost:8080/MJServer/video?method=get&type=XML"];
    //2. 创建请求
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    //3. 创建异步连接
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
        
        // 容错处理
        if (connectionError) {
            return ;
        }
        
        // 4. 解析数据(反序列化)
        NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
        parser.delegate = self;
        
        // 开始解析: parse方法是 阻塞的, 只有把解析完,才会 调用reloadData
        [parser parse];
        //5. 刷新UI
        [self.tableView reloadData];
        
    }];
}

#pragma -mark NSXMLParser代理方法
// 开始解析
- (void)parserDidStartDocument:(NSXMLParser *)parser
{
    NSLog(@"开始解析----");
}

// 开始解析某个元素
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
//    NSLog(@"%@---%@",elementName,attributeDict);
    
    // SAX解析, 一个一个节点 解析
    if ([elementName isEqualToString:@"videos"]) {
        return;
    }
    
    // 字典转模型
    [self.videos addObject:[ZYVideo mj_objectWithKeyValues:attributeDict]];
    
    
}

// 某个元素解析完毕
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    NSLog(@"%@",elementName);
}

// 结束解析
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
    NSLog(@"结束解析----");
}

#pragma -mark tableView数据源方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.videos.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //1. 设置重用标识
    static NSString *ID = @"video";
    //2. 在缓存池中复用cell(如果没有会自动创建)
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    //3. 设置数据
//    NSDictionary *dict = self.videos[indexPath.row];
    ZYVideo *video = self.videos[indexPath.row];
    
    cell.textLabel.text = video.name;
    cell.detailTextLabel.text = [NSString stringWithFormat:@"播放时间:%@",video.length];
    // 使用SDWebImage设置网络中下载的图片
    // 拼接图片的url
//    NSString *baseUrlStr = @"https://120.25.226.186:32812";
    NSString *urlStr = [baseUrlStr stringByAppendingPathComponent:video.image];
    [cell.imageView sd_setImageWithURL:[NSURL URLWithString:urlStr] placeholderImage:[UIImage imageNamed:@"qq"]];
    
//    NSLog(@"----%@",video.ID);
    
    return cell;
    
}

#pragma -mark tableView的代理方法
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    //1. 拿到数据
//    NSDictionary *dict = self.videos[indexPath.row];
    ZYVideo *video = self.videos[indexPath.row];
    //2. 拼接资源路径
    NSString *urlStr = [baseUrlStr stringByAppendingPathComponent:video.url];
    //3. 创建播放器
    MPMoviePlayerViewController *mpc = [[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL URLWithString:urlStr]];
    //4. 弹出控制器
    [self presentViewController:mpc animated:YES completion:nil];
}

@end

DOM解析:(GDataXMLDocument)

使用DOM解析前的配置工作:

1. 导入 GDataXML文件.

iOS网络开发教程之XML解析

iOS网络开发教程之XML解析

iOS网络开发教程之XML解析

#import "ViewController.h"
#import "UIImageView+WebCache.h"
#import 
#import "ZYVideo.h"
#import "MJExtension.h"
#import "GDataXMLNode.h"

#define baseUrlStr @"https://120.25.226.186:32812"

@interface ViewController ()
/* 存储模型的 数组 */
@property (nonatomic, strong) NSMutableArray *videos;

@end

@implementation ViewController

- (NSMutableArray *)videos
{
    if (!_videos) {
        _videos = [NSMutableArray array];
    }
    return _videos;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 替换 模型中属性的名称 和 系统关键字冲突.(系统自带方法冲突)
    [ZYVideo mj_setupReplacedKeyFromPropertyName:^NSDictionary *{
        return @{
                 @"ID" : @"id"
                 };
    }];
    
    //1. 确定url
    NSURL *url = [NSURL URLWithString:@"https://localhost:8080/MJServer/video?method=get&type=XML"];
    //2. 创建请求
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    //3. 创建异步连接
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
        
        // 容错处理
        if (connectionError) {
            return ;
        }
        
        // 4. 解析数据(反序列化)
        // 4.1 加载整个XML文档
        GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:data options:kNilOptions error:nil];
        //4.2 XML文档的根元素. 拿到根元素内部的 所有名称为video的子孙元素
        NSArray *eles = [doc.rootElement elementsForName:@"video"];
        //4.3 遍历操作
        for (GDataXMLElement *ele in eles) {
            // 拿到子元素中的属性 ---> 模型 ---> 添加到self.videos
            ZYVideo *video = [[ZYVideo alloc] init];
            video.name = [ele attributeForName:@"name"].stringValue;
            video.length = [ele attributeForName:@"length"].stringValue;
            video.image = [ele attributeForName:@"image"].stringValue;
            video.ID = [ele attributeForName:@"id"].stringValue;
            video.url = [ele attributeForName:@"url"].stringValue;
            
            [self.videos addObject:video];
        }
        
        //5. 刷新UI
        [self.tableView reloadData];
        
    }];
}


#pragma -mark tableView数据源方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.videos.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //1. 设置重用标识
    static NSString *ID = @"video";
    //2. 在缓存池中复用cell(如果没有会自动创建)
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    //3. 设置数据
    //    NSDictionary *dict = self.videos[indexPath.row];
    ZYVideo *video = self.videos[indexPath.row];
    
    cell.textLabel.text = video.name;
    cell.detailTextLabel.text = [NSString stringWithFormat:@"播放时间:%@",video.length];
    // 使用SDWebImage设置网络中下载的图片
    // 拼接图片的url
    //    NSString *baseUrlStr = @"https://120.25.226.186:32812";
    NSString *urlStr = [baseUrlStr stringByAppendingPathComponent:video.image];
    [cell.imageView sd_setImageWithURL:[NSURL URLWithString:urlStr] placeholderImage:[UIImage imageNamed:@"qq"]];
    
    //    NSLog(@"----%@",video.ID);
    
    return cell;
    
}

#pragma -mark tableView的代理方法
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    //1. 拿到数据
    //    NSDictionary *dict = self.videos[indexPath.row];
    ZYVideo *video = self.videos[indexPath.row];
    //2. 拼接资源路径
    NSString *urlStr = [baseUrlStr stringByAppendingPathComponent:video.url];
    //3. 创建播放器
    MPMoviePlayerViewController *mpc = [[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL URLWithString:urlStr]];
    //4. 弹出控制器
    [self presentViewController:mpc animated:YES completion:nil];
}

@end       

iOS网络开发教程之XML解析