• XML 数据解析方式


    XML 全称是 Extensible Markup Language,译作“可扩展标记语言”, 是常用的一种用于交互的数据格式, 一般也叫XML文档(XML Document).

    XML 举例:

    <videos>
        <video name="X战警 第一战" length="120" />
        <video name="X战警 逆转未来" length="150" />
        <video name="X战警 天启" length="118" />
    </videos>

    XML语法

    一个常见的XML文档一般由以下部分组成
    (1) 文档声明
    (2) 元素(Element)
    (3) 属性(Attribute)

    XML语法 – 文档声明

    在XML文档的最前面,必须编写一个文档声明,用来声明XML文档的类型
    (1) 最简单的声明

    <?xml version="1.0" ?>

    (2) 用encoding属性说明文档的字符编码

    <?xml version="1.0" encoding="UTF-8" ?>

    XML语法 – 元素(Element)

    一个元素包括了开始标签和结束标签
    拥有元素内容:<video>X战警</video>
    没有元素内容:<video></video>(简写:<video/> )
    一个元素可以嵌套若干个子元素(不能出现交叉嵌套)

    <videos>
        <video>
            <name>X战警 第一战</name>
                 <length>120</length>
        </video>
    </videos>

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

    XML语法 –元素的注意

    XML中的所有空格和换行,都会当做具体内容处理
    下面两个元素的内容是不一样的
    第1个

    <video>X战警</video>

    第2个

    <video>
        X战警
    </video>

    XML语法 – 属性(Attribute)

    一个元素可以拥有多个属性

    video元素拥有name和length两个属性
    属性值必须用 双引号”” 或者 单引号” 括住
    实际上,属性表示的信息也可以用子元素来表示,比如

    <video>
        <name>X战警 第一战</name>
            <length>120</length>
    </video>

    XML解析

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

    iOS中的XML解析

    在iOS中,解析XML的手段有很多
    苹果原生
    NSXMLParser:SAX方式解析,使用简单
    第三方框架
    libxml2:纯C语言,默认包含在iOS SDK中,同时支持DOM和SAX方式解析
    GDataXML:DOM方式解析,由Google开发,基于libxml2

    XML解析方式的选择建议
    大文件:NSXMLParser、libxml2
    小文件:GDataXML

    NSXMLParser
    使用步骤

    // 传入XML数据,创建解析器
    NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
    // 设置代理,监听解析过程
    parser.delegate = self;
    // 开始解析
    [parser parse];

    NSXMLParser采取的是SAX方式解析,特点是事件驱动,下面情况都会通知代理

    //当扫描到文档(Document)的开始与结束
    //当扫描到元素(Element)的开始与结束
    //当扫描到文档的开始时调用(开始解析)
    - (void)parserDidStartDocument:(NSXMLParser *)parser
    //当扫描到文档的结束时调用(解析完毕)
    - (void)parserDidEndDocument:(NSXMLParser *)parser
    //当扫描到元素的开始时调用(attributeDict存放着元素的属性)
    - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
    //当扫描到元素的结束时调用
    - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName

    XML示例:

    {"videos":[{"id":1,"image":"resources/images/01.png","length":10,"name":"第01部","url":"resources/videos/01.mp4"},{"id":2,"image":"resources/images/02.png","length":12,"name":"第02部","url":"resources/videos/02.mp4"},{"id":3,"image":"resources/images/03.png","length":14,"name":"第03部","url":"resources/videos/03.mp4"},{"id":4,"image":"resources/images/04.png","length":16,"name":"第04部","url":"resources/videos/04.mp4"},{"id":5,"image":"resources/images/05.png","length":18,"name":"第05部","url":"resources/videos/05.mp4"},{"id":6,"image":"resources/images/06.png","length":20,"name":"第06部","url":"resources/videos/06.mp4"},{"id":7,"image":"resources/images/07.png","length":22,"name":"第07部","url":"resources/videos/07.mp4"},{"id":8,"image":"resources/images/08.png","length":24,"name":"第08部","url":"resources/videos/08.mp4"},{"id":9,"image":"resources/images/09.png","length":26,"name":"第09部","url":"resources/videos/09.mp4"},{"id":10,"image":"resources/images/10.png","length":28,"name":"第10部","url":"resources/videos/10.mp4"},{"id":11,"image":"resources/images/11.png","length":30,"name":"小黄人 第11部","url":"resources/videos/11.mp4"},{"id":12,"image":"resources/images/12.png","length":32,"name":"第12部","url":"resources/videos/12.mp4"},{"id":13,"image":"resources/images/13.png","length":34,"name":"第13部","url":"resources/videos/13.mp4"},{"id":14,"image":"resources/images/14.png","length":36,"name":"第14部","url":"resources/videos/14.mp4"},{"id":15,"image":"resources/images/15.png","length":38,"name":"第15部","url":"resources/videos/15.mp4"},{"id":16,"image":"resources/images/16.png","length":40,"name":"第16部","url":"resources/videos/16.mp4"}]}
    
    //模型为:
    //.h文件
    #import <Foundation/Foundation.h>
    @interface XMLModel : NSObject
    
    @property (nonatomic, copy) NSString *ID;
    @property (nonatomic, copy) NSString *image;
    @property (nonatomic, assign) int length;
    @property (nonatomic, copy) NSString *name;
    @property (nonatomic, copy) NSString *url;
    
    - (instancetype)initWithDic:(NSDictionary *)dict;
    + (instancetype)xmlModelInitDic:(NSDictionary *)dict;
    @end
    
    //.m文件
    #import "XMLModel.h"
    @implementation XMLModel
    
    - (instancetype)initWithDic:(NSDictionary *)dict{
        self = [super init];
        if (self) {
            //KVC
            [self setValue:dict[@"id"] forKeyPath:@"ID"];
            [self setValue:dict[@"image"] forKeyPath:@"image"];
            [self setValue:dict[@"name"] forKeyPath:@"name"];
            [self setValue:dict[@"url"] forKeyPath:@"url"];
            [self setValue:dict[@"length"] forKeyPath:@"length"];
            //[self setValuesForKeysWithDictionary:dict];
        }
        return self;
    }
    
    + (instancetype)xmlModelInitDic:(NSDictionary *)dict{
        return [[self alloc] initWithDic:dict];
    }
    @end

    XML 解析代码示例:

    /**
     *  SAX 方式解析 XML
     */
    - (void)saxXML{
        NSURL *url = [NSURL URLWithString:@"http://localhost:8080/Server/video?type=XML"];
    
        NSURLRequest *request = [NSURLRequest requestWithURL:url];
    
        NSURLSession *session = [NSURLSession sharedSession];
        NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            if (data == nil || error ) {
                NSLog(@"网络错误--%@", error);
            }
            //SAX 方式解析 XML
            NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
            //成为自己的代理
            parser.delegate = self;
            //开始解析
            [parser parse]; 
        }];
        [task resume];
    }
    
    #pragma mark - NSXMLParserDelegate 代理方法
    /** 解析到开头调用 */
    - (void)parserDidStartDocument:(NSXMLParser *)parser{
        NSLog(@"parserDidStartDocument");
    }
    /**
     *  解析到第一个元素调用
     *
     *  @param elementName   元素名称
     *  @param attributeDict 属性字典
     */
    - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict{
        //NSLog(@"didStartElement -- %@", attributeDict);
    
        if ([@"videos" isEqualToString:elementName]) return;
        //模型数据
        XMLModel *xml = [XMLModel xmlModelInitDic:attributeDict];
    }
    
    /** 解析到最后一个元素调用 */
    - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
        NSLog(@"didEndElement");
    }
    
    /** 解析到结尾调用 */
    - (void)parserDidEndDocument:(NSXMLParser *)parser{
        NSLog(@"parserDidEndDocument");
    }

    GDataXML配置

    GDataXML基于libxml2库,得做以下配置
    (1) 导入libxml2库
    (2) 设置libxml2的头文件搜索路径(为了能找到libxml2库的所有头文件)
    在PROJECT -> build setting -> ALL -> Head Search Path中加入/usr/include/libxml2
    (3) 设置链接参数(自动链接libxml2库)
    在Other Linker Flags中加入-lxml2
    (4) 在 Build Phases 中的GDataXMLNode.m加入 -fno-objc-arc

    示例代码

    /**
     *  DOM 方式解析 XML
     */
    - (void)domXML{
        NSURL *url = [NSURL URLWithString:@"http://localhost:8080/Server/video?type=XML"];
    
        NSURLRequest *request = [NSURLRequest requestWithURL:url];
    
        NSURLSession *session = [NSURLSession sharedSession];
        NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            if (data == nil || error ) {
                NSLog(@"网络错误--%@", error);
            }
            //DOM方式解析XML
            GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:data options:0 error:nil];
            //获取根元素
            GDataXMLElement *root = doc.rootElement;
    
            //获取根元素里面所有的的video元素
            NSArray *array = [root elementsForName:@"video"];
            //遍历void元素
            for (GDataXMLElement *videoElement in array){
        //模型数据
                XMLModel *xmlModel = [[XMLModel alloc] init];
                xmlModel.ID = [videoElement attributeForName:@"id"].stringValue;
                xmlModel.name = [videoElement attributeForName:@"name"].stringValue;
                xmlModel.url = [videoElement attributeForName:@"url"].stringValue;
                xmlModel.length = [videoElement attributeForName:@"length"].stringValue.intValue;
                xmlModel.image = [videoElement attributeForName:@"image"].stringValue;
        }];
        [task resume];
    }
  • 相关阅读:
    时间的计算
    中英文词频统计
    组合数据类型,英文词频统计
    作业二
    学号提取
    用for循环产生的网址
    温度转换
    身份证号码提取
    数字游戏
    更改mysql连接个数
  • 原文地址:https://www.cnblogs.com/xiaocai-ios/p/7779768.html
Copyright © 2020-2023  润新知