• iOS- JSon和Xml解析,与服务器交互数据的解析详解与使用,各种解析方式详解


    JSon和Xml解析,与服务器交互必许学会

    什么是JSon?什么是Xml?

    在移动应用开发中,客户端经常要与服务器进行交互,获得服务器的数据,进行展示。那么获取的数据的格式,就是JSon或者Xml格式(大多数),而现在,因为JSon格式的轻量级,和方便使用的特性,在市场占有中已经90%左右。

    我们先学习一下JSon格式的数据

    我们来看看JSon格式的数据长什么样子:

     {
    
           "access_token": "ACCESS_TOKEN",
    
           "expires_in": 1234,
    
           "remind_in":"798114",
    
           "uid":"12341234"
    
     }
    

    这是一段新浪微博返回的JSon格式数据,是不是觉得样子长得很像OC中的字典,对,没错,在iOS开发中我们也是要将这种数据转化成OC的数据类型,方便我们使用。

    在上面的数据中,我们注意到:JSon数据的key都有“”包裹,这说明你观察的挺仔细的。这也是JSon数据的格式要求,那么,JSon数据怎么转换成OC的数据类型呢???我们先看看他们之间的联系吧。

    你要是还不清楚这张图在说什么,就看看下面的对应关系:

    JSON数据(NSData) -> OC对象(Foundation Object)

    • {} -> NSDictionary @{}
    • [] -> NSArray @[]
    • "jack" -> NSString @"jack"
    • 10 -> NSNumber @10
    • 10.5 -> NSNumber @10.5
    • true -> NSNumber @1
    • false -> NSNumber @0
    • null -> NSNull

    这下肯定知道什么意思了吧。

    有了这个一一对应的关系,我们就能方便的进行转换了。
    JSon解析方法

    性能最好的解析方法是:苹果原生(自带):NSJSONSerialization

    也有第三方框架:JSONKit、SBJson、TouchJSON(性能从左到右,越来越差)

    但是我们并不会都学,因为学那么多也不会都用得上,so...开始吧


    我们来学习一下性能最好的解析方式:
    NSJSONSerialization

    常使用的方法是:


    将JSON数据 -> 转换成OC对象

    + (id)JSONObjectWithData:(NSData *)data options:(NSJSONReadingOptions)opt error:(NSError **)error;
    

    参数options详解:

    - NSJSONReadingOptions
        - NSJSONReadingMutableContainers = (1UL << 0)
            - 创建出来的数组和字典就是可变
        - NSJSONReadingMutableLeaves = (1UL << 1)
            - 数组或者字典里面的字符串是可变的
        - NSJSONReadingAllowFragments
            - 允许解析出来的对象不是字典或者数组,比如直接是字符串或者NSNumber
    

    这样干讲是不是觉得学的不牢固,那么我们来试试例子学习吧:

    例子

    //请求服务器的数据
        NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=520it&pwd=520it&type=JSON"];
        NSURLRequest *request = [NSURLRequest requestWithURL:url];
        [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
            //查看原数据的类型
            NSLog(@"原数据%@",data);
            //对数据用NSJSONSerialization解析成OC数据类型
            NSMutableDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
            NSLog(@"转换后的数据%@",dict);
        }];
    
    

    上面的例子你可以实现将服务器返回的数据转换成OC的数据


    将OC对象 -> 转换成JSON数据

    函数原型

    + (NSData *)dataWithJSONObject:(id)obj options:(NSJSONWritingOptions)opt error:(NSError **)error;
    

    参数:NSJSONWritingPrettyPrinted 表示: 对转换之后的JSON进行排版

    举例论证

    //创建字典
        NSDictionary *dict = @{
                                @"name": @"xueyinliang",
                                @"car":@"baoma",
                                @"id":@1
                               };
        NSLog(@"%@",dict);
        //将字典转换成JSon数据
        NSData *data =[NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:nil];
        NSLog(@"%@",data);
    

    打印结果:

    2015-08-11 15:32:46.890 JSonAndOC[4767:149687] {
        car = baoma;
        id = 1;
        name = xueyinliang;
    }
    2015-08-11 15:32:46.894 JSonAndOC[4767:149687] <7b0a2020 226e616d 6522203a 20227875 6579696e 6c69616e 67222c0a 20202263 61722220 3a202262 616f6d61 222c0a20 20226964 22203a20 310a7d>
    

    这样,我们就轻松学会了JSon和OC数据类型的转换了。


    xml数据的解析

    虽然,JSon数据的市场应用占有率很大,但是我们还是要学习一下XML数据的解析。因为这种格式的数据还是有一些公司会用到的。

    xml数据长什么样子?

    xml数据是一种可扩展的标记语言,因为它的每一个元素都是由特定的标记扩起来的。

    例如:
    每一个元素都有一个开始和结束标签

    <video>元素名</video>
    

    元素可以嵌套子元素

    <video>
        <name>世界你好</name>
        <length>30</length>
    </video>
    

    所有元素前面要有声明

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

    注意:这里的所有空格和换行,也是数据的一部分,会被处理。这也是为什么xml数据容量大的原因。

    下面,我们来学习一下怎么解析xml数据,这才是重点。

    XML数据的解析方式

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

    然而,我们怎么选择和怎么使用这两种解析方式呢?


    下面将给出选择方案:(基于两种方式的特点选择)

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

    我们必须知道上面的这几种方法各有什么特点,才会使用:

    苹果原生

    NSXMLParser:SAX方式解析,使用简单
    

    第三方框架

    libxml2:纯C语言,默认包含在iOS SDK中,同时支持DOM和SAX方式解析
    GDataXML:DOM方式解析,由Google开发,基于libxml2
    
    

    虽然libxml2可以同时支持dom和sax方式的解析,但是因为其使用麻烦,所以在实际开发中,并不常用,而是SAX方式解析大文件的时候使用NSXMLParser,DOM方式解析小文件的时候使用GDataXML或NSXMLParser。


    XML解析的方式介绍过了,我们再来看看到底怎么使用他们吧。

    首先是如何使用NSXMLParser

    使用NSXMLParser解析数据很简单,你只需要传递过来XML数据,然后在NSXMLParser的代理方法里面解析就好了。这时候NSXMLParser的代理方法会当读到XML文件的开头和结尾,以及读到元素标签的开始和结尾的时候通知代理,并调用相应的代理方法来执行。为了防止有朋友不清楚哪里是XML文件的开头和结尾,哪里是元素的开头和结尾,这里给出一张图来明确表示一下:

    下面给出代码如何开始和如何设置代理方法:

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

    代理方法

    当扫描到文档的开始时调用(开始解析)
    - (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
    
    /**
     *  解析发生错误时调用
     */
    - (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError;
    
    

    举例

    在获取到网络数据以后:

    // 1.创建XML解析器
    NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
    
    // 2.成为NSXMLParser的代理
    parser.delegate = self;
    
    // 3.开始解析XML
    [parser parse];
    

    然后在代理方法中拿到数据:

    /**
     *  开始解析XML文档中的每一个元素时调用
     */
    - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
    {
        // 2.videos
        // 3.video
        // 5.video
        if ([elementName isEqualToString:@"videos"]) {
            return;
        }
        
        XMGVideo *video = [XMGVideo objectWithKeyValues:attributeDict];//使用MJExtension转换模型
        [self.videos addObject:video];
    }
    
    

    然后就可以拿到数据数组,进行各种显示的操作了


    接下来我们看看GDATAXML怎么使用

    1,GDataXML基于libxml2库,得做以下配置

    • 导入libxml2库

    • 设置libxml2的头文件搜索路径(为了能找到libxml2库的所有头文件)
      在Head Search Path中加入/usr/include/libxml2

    • 设置链接参数(自动链接libxml2库)
      在Other Linker Flags中加入-lxml2

    • 由于GDataXML是非ARC的,因此得设置编译参数

    GDataXML中常用的类

    • GDataXMLDocument:代表整个XML文档

    • GDataXMLElement
      代表文档中的每个元素

    • 使用attributeForName:方法可以获得属性值

    举例

    在获取到网络数据以后:

     // 1.加载所有的xml到内存中
            GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:data options:kNilOptions error:nil];
            // 2.获取根元素
            GDataXMLElement *rootElement = doc.rootElement;
            // 3.从根元素中获取所有子元素
            NSArray *elements = [rootElement elementsForName:@"video"];
            // 4.将子元素中的属性转换为模型
            for (GDataXMLElement *ele in elements) {
                XMGVideo *video = [[XMGVideo alloc] init];
                video.image = [ele attributeForName:@"image"].stringValue;
                video.url = [ele attributeForName:@"url"].stringValue;
                video.name = [ele attributeForName:@"name"].stringValue;
                video.length = @([ele attributeForName:@"length"].stringValue.integerValue);
                [self.dataArray addObject:video];
                //dataArray是数据的数组
            }
    

    然后就可以拿到数据数组,进行各种显示的操作了

    如果还有哪里不懂的,可以联系我的邮箱492199045@qq.com

  • 相关阅读:
    监听
    用户管理
    oracle网络
    实例 参数
    存储管理
    oracle 体系
    实例
    修改
    集合操作
    17.08.18
  • 原文地址:https://www.cnblogs.com/66it/p/4722851.html
Copyright © 2020-2023  润新知