• week 5 analyse json/xml


    前言:
    在做web或者其他项目中,JSON与XML格式的数据是大家经常会碰见的2种。在与各种平台做数据对接的时候,JSON与XML格式也是基本的数据传递格式,本文主要简单的介绍JSON/XML文件的读写操作,以及与Bean之间的转换。示例代码都是经过Demo测试的,当然也会把代码上传到GitHub.需要的朋友可以看看。
    准备工作
         我这里对XML与JSON主要依赖以下2个开源库,当然像针对xml和JSON解析的开源库非常的多,下面这2个感觉相对用起来比较简单。需要注意的是如果缺少下面jar文件中的一个,可能就会出现ClassNotFound 异常,如果发现使用的方法在当前库中找不到,则可能是库版本不同造成的,可以去官网查阅。
    1.JSON解析库:
    Jackson JSON Processor
    官网:http://jackson.codehaus.org/
    2.XML解析库 :
    Simple XML serialization framework
    官网:http://simple.sourceforge.net/home.php
    一.JSON简介
    AVAScript Object Notation是一种轻量级的数据交换格式
    具有良好的可读和便于快速编写的特性。
    业内主流技术为其提供了完整的解决方案(有点类似于正则表达式 ,获得了当今大部分语言的支持)
    JSON采用兼容性很高的文本格式,同时也具备类似于C语言体系的行为。 – Json.org
    JSON作为数据是目前网络中主流的数据传输格式之一,应用十分广泛,说是使用率达到99%一点也不勉强
    二.JSON语法
    JSON 语法
    作用: JSON文本是类似XML文本文件,用来储存和传输数据信息的的媒介
    注: JSON同XML一样,不仅可以通过响应文件作为数据的载体,也可以通过满足语法字符串作为对应数据的载体 称之为 “json字符串”
    json数据存储采用{}与[]语法
    {} => java中的双列集合 (字典)
    [] => java中的单列集合 (数组)

    json语法最顶层为 单一{} 或 单一[]
    json语法中结构为 {} [] 相互嵌套({}可以嵌套{}[],[]也可以相互嵌套{}[])
    json语法中以逗号(,)作为字段分割的标识(注: 最后一个字段不能添加逗号)
    字典中语法为 {“key”:value}格式 (注: key为字符串)
    多条语句语法:
    {
    “key1”: value1,
    “key2”: value2,
     …  :  … ,
     “keyn”: valuen
    }
    数组中语法为[value1,value2,value3] 格式(注: value拥有类型)
    数字(整数或浮点数)
    逻辑值(true 或 false)
    字符串(在双引号中)
    数组(在方括号中)
    函数
    对象(在大括号中)
    null
    {}和[]中的每一个value均可以为{}|[] ,且多个value类型不一定相同

    7.我们在JSON解析中只有三中情况出现
     1.{} 解析’大括号’类型 
     2. [ ] 解析是’中括号’类型 
     3. 其实只有两种,那第三种则是1与2的组合方法即”{”name”:”小东吖”,”hobby”:[“编程”,”电竞”,”睡觉”]}”那么下面分别来看一些这三种类型以及解析
    三.解析JSON
    SON解析一定要掌握的两条规则:
    1.如果看到是{ }–>使用JSONObject
    2.如果看到的[ ]–>使用JSONArray解析
    12
    掌握了JSON的数据类型和基本语法后,我们对JSON的各种语法类型进行详细解析(注意掌握两条规则的使用,掌握了JSON解析就那么回事)
            // JSON字符串以{}包裹,解析为JSONObject对象
            // JSON字符串以[]包裹,解析为JSONArray对象
    
            // 纯数组解析
        public static void main(String[] args) {
            String string = "["天津","上海","北京","南京"]";
            // []是数组 将其解析为JSONArray数组即可 拥有数组的方法
            JSONArray jsonArray = JSON.parseArray(string);
            System.out.println(jsonArray);
    
            // 纯对象解析
            String oString = "{"name" : "小东吖" }";
            // 大括号是对象类型的 解析为JSONObject类型即可
            JSONObject jsonObject = JSON.parseObject(oString);
            // parseObject的参数(字符串,类名.class); 就可解析为对象
            Student student = jsonObject.parseObject(oString, Student.class);
            System.out.println(student);
    public class Student {
        private String name;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        // toString方法用于控制台输出  
        @Override
        public String toString() {
            return "Student [name=" + name + "]";
        }

    可以详见博客https://blog.csdn.net/zlsuperjj/article/details/80039143

    java中Xml、json之间的相互转换可参见博客:https://www.cnblogs.com/tv151579/p/3516674.html

    1.第一种方法(个人实现的)

    使用JSON-JAVA提供的方法,之前一直使用json-lib提供的方法转json,后来发现了这个开源项目,觉得用起来很不错,并且可以修改XML.java中的parse方法满足自己的转换需要。

    (1)首先去git下载所需的java文件,并导入项目

    Git:https://github.com/stleary/JSON-java

    (2)使用XML.java中提供的XML.toJSONObject(xml)方法即可完成xml到json的转换,同时也可以对JSON进行格式化

    [java] view plain copy
     
    1. /* 第一种方法,使用JSON-JAVA提供的方法 */  
    2.        //将xml转为json  
    3.        JSONObject xmlJSONObj = XML.toJSONObject(xml);  
    4.        //设置缩进  
    5.        String jsonPrettyPrintString = xmlJSONObj.toString(4);  
    6.        //输出格式化后的json  
    7.        System.out.println(jsonPrettyPrintString);  



    2.第二种方法

    使用json-lib的XMLSerializer对象

    (1)创建XMLSerializer对象

    (2)使用XMLSerializer的read(xml)方法即可

    [java] view plain copy
     
    1. /* 第二种方法,使用json-lib提供的方法 */  
    2.  //创建 XMLSerializer对象  
    3.  XMLSerializer xmlSerializer = new XMLSerializer();  
    4.  //将xml转为json(注:如果是元素的属性,会在json里的key前加一个@标识)  
    5.  String result = xmlSerializer.read(xml).toString();  
    6.  //输出json内容  
    7.  System.out.println(result);  

    3.测试

    [java] view plain copy
     
    1. public class Test {  
    2.     public static void main(String[] args) {  
    3.         String xml = "<class id="  
    4.                 + "'1'"  
    5.                 + "><student><name>aaaaaa</name><age>21</age></student><student><name>bbbbbb</name><age>22</age></student></class>";  
    6.   
    7.         /* 第一种方法,使用JSON-JAVA提供的方法 */  
    8.         //将xml转为json  
    9.         JSONObject xmlJSONObj = XML.toJSONObject(xml);  
    10.         //设置缩进  
    11.         String jsonPrettyPrintString = xmlJSONObj.toString(4);  
    12.         //输出格式化后的json  
    13.         System.out.println(jsonPrettyPrintString);  
    14.   
    15.         /* 第二种方法,使用json-lib提供的方法 */  
    16.         //创建 XMLSerializer对象  
    17.         XMLSerializer xmlSerializer = new XMLSerializer();  
    18.         //将xml转为json(注:如果是元素的属性,会在json里的key前加一个@标识)  
    19.         String result = xmlSerializer.read(xml).toString();  
    20.         //输出json内容  
    21.         System.out.println(result);  
    22.   
    23.     }  

    第一种方法输出:

    [java] view plain copy
     
    1. {"class": {  
    2.     "id": 1,  
    3.     "student": [  
    4.         {  
    5.             "age": 21,  
    6.             "name": "aaaaaa"  
    7.         },  
    8.         {  
    9.             "age": 22,  
    10.             "name": "bbbbbb"  
    11.         }  
    12.     ]  
    13. }}  


    第二种方法输出:

    [java] view plain copy
     
      1. {"@id":"1","student":[{"name":"aaaaaa","age":"21"},{"name":"bbbbbb","age":"22"}]}  

    源码下载:http://download.csdn.net/detail/lom9357bye/9690304

    json转换成model技巧

    在项目中从服务器获取数据的时候,经常采用json格式的数据,为了能方便的使用这些数据,项目中会把json转化为model。
    之前我们的项目中是这么用的:
     
    很复杂,很乱,对不对,然而这才只是二十多个字段中的5个,(:зゝ∠),一定有更好的方法。
    如果我们能够在动态地去获取对象的属性名就好了,只要json的key和对象的属性名一样,那么就可以利用for循环以可kvc赋值了。在Java中,我们可以利用反射来做到这一点,同样的,在OC中,我们可以利用runtime的特性来实现。
    代码如下:
      
        NSDictionary *dic = @{@"name" : @"小王",
    
                              @"no"   : @"123",
    
                              @"rank" : @1,
    
                              @"sex"  : @0};
    
        Student *student = [[Student alloc] init];
    
        u_int count;
    
        objc_property_t *properties  =class_copyPropertyList([Student class], &count);
    
        for (int i = 0;i<count;i++)
    
        {
    
            const char* propertyName =property_getName(properties[i]);
    
            NSString *property = [NSString stringWithUTF8String: propertyName];
    
            [student setValue:dic[property] forKey:property];
    
        }
    
        free(properties)

    结果如下,DONE!:
     
     
    优点:这种扩展性强,并且与dic存储的类型无关,例如将@"rank" : @1改成@"rank" : @"1"后,也能得到正确的输出。
    缺点;但是要求属性名和接口返回json数据中的key一一对应。
    扩展一
    封装一下,让Model类继承基类就可以直接使用。创建一个JsonModel类,代码如下:
    #import "JsonModel.h"
    
    #import "objc/runtime.h"
    
     
    
    @implementation JsonModel
    
     
    
    - (id)initWithDic:(NSDictionary *)dic {
    
        self = [super init];
    
        if (self) {
    
            u_int count;
    
            objc_property_t *properties  =class_copyPropertyList([self class], &count);
    
            for (int i = 0;i<count;i++) {
    
                const char* propertyName =property_getName(properties[i]);
    
                NSString *property = [NSString stringWithUTF8String: propertyName];
    
                [self setValue:dic[property] forKey:property];
    
            }
    
            free(properties);
    
        }
    
        return self;
    
    }
    
     
    
    @end
    
     
    使用时,让Student类继承JsonModel类,然后就可以方便的初始化Student类了。
    Student *student = [[Student alloc] initWithDic:dic];
    扩展二
    如果由于各种原因,接口返回数据的key和model的属性名不能统一,那么如何处理呢?初步想法是构造一个映射关系,代码如下:
    #import "JsonModel.h"
    
    #import "objc/runtime.h"
    
     
    
    @implementation JsonModel
    
     
    
    - (id)initWithDic:(NSDictionary *)dic {
    
        self = [super init];
    
        if (self) {
    
            u_int count;
    
            objc_property_t *properties  =class_copyPropertyList([self class], &count);
    
            for (int i = 0;i<count;i++) {
    
                const char* propertyName =property_getName(properties[i]);
    
                NSString *property = [NSString stringWithUTF8String: propertyName];
    
                [self setValue:dic[property] forKey:property];
    
            }
    
            free(properties);
    
        }
    
        return self;
    
    }
    
     
    
    @end
    
     

    使用方法:通过重写静态方法getKeyAndPropertyCorrelation去设置关系映射表。
    扩展三
    github上有一个开源Json解析第三方库JsonModel,包含了很多强大的功能。
  • 相关阅读:
    iOS-Block的多种使用
    iOS-验证码倒计时60秒
    iOS-AFNetworking-上传图片
    Xcode 报错信息
    iOS-定时器
    iOS-开发技巧-页面布局
    iOS-nil,Nil,NULL的区别
    iOS-Debug
    iOS-NSDate
    iOS-生命周期
  • 原文地址:https://www.cnblogs.com/EST-woah/p/10621050.html
Copyright © 2020-2023  润新知