iOS开发网络篇 一一 XML解析

XML简介

什么是XML?

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

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

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

XML举例
<videos>
    <video name="小黄人 第01部" length="30" />
    <video name="小黄人 第02部" length="19" />
    <video name="小黄人 第03部" length="33" />
</videos>


XML语法:

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

文档声明

元素 ( Element )

一个元素包括了开始标签和结束标签
拥有内容的元素:<video>小黄人</video>
没有内容的元素:<video></video>
没有内容的元素简写:<video/> 

一个元素可以嵌套若干个子元素(不能出现交叉嵌套)
<videos>
    <video>
        <name>小黄人 第01部</name>
       	  <length>30</length>
    </video>
</videos>

规范的XML文档最多只有1个根元素,其他元素都是根元素的子孙元素

属性 ( Attribute )

一个元素可以拥有多个属性
<video name="小黄人 第01部" length="30" />
video元素拥有name和length两个属性
属性值必须用 双引号"" 或者 单引号'' 括住

实际上,属性表示的信息也可以用子元素来表示,比如
<video>
    <name>小黄人 第01部</name>
        <length>30</length>
</video>

XML解析

XML的解析方式有2种

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


SAX解析:( NSXMLParser )

#import "ViewController.h"
#import "UIImageView+WebCache.h"
#import <MediaPlayer/MediaPlayer.h>
#import "ZYVideo.h"
#import "MJExtension.h"

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

@interface ViewController ()<NSXMLParserDelegate>
/* 存储模型的 数组 */
@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:@"http://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<NSString *,NSString *> *)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 = @"http://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文件.




#import "ViewController.h"
#import "UIImageView+WebCache.h"
#import <MediaPlayer/MediaPlayer.h>
#import "ZYVideo.h"
#import "MJExtension.h"
#import "GDataXMLNode.h"

#define baseUrlStr @"http://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:@"http://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 = @"http://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       



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

white camel

感谢支持~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值