美文网首页ios知识积累程序员iOS 开发
[程序员日记]OC中JSON解析与XML解析

[程序员日记]OC中JSON解析与XML解析

作者: KeyLiu7 | 来源:发表于2015-12-26 22:50 被阅读1959次

    一.JSON解析

    1.实质

    将返回的数据放入模型(model)中 json(相对于xml的数据,轻巧,传输速率高,冗余的数据少。缺点:可读性差些)

    xml(冗余的数据多,优点:可读性强,扩展性强)

    2.解析步骤

    (1)查看解析文档,建立模型类

    如解析文档为:

      {
       "name" : “三年一班”,
      "number" : 14,
      "students" : [
       {
         "age" : 20,
         "mark" : 90,
         "name" : "张亮"
       },
       {
          "age" : 21,
          "mark" : 89,
          "name" : "王凯"
       },
    
       ],
          "teacher" : {
           "age" : 18,
          "lesson" : "OC",
          "name" : "Lucy"
          }
       }
    

    建立模型对象为:

    学生(Student类),含有age(NSInteger),mark(NSInteger),name(NSString)三个属性

    @interface Student : NSObject
    @property(nonatomic,assign)NSInteger age;
    @property(nonatomic,assign)NSInteger mark;
    @property(nonatomic,copy)NSString *name;
    @end
    

    讲师(Teacher类),含有age(NSInteger),lesson(NSString),name(NSString)三个属性

    @interface Teacher : NSObject
    @property(nonatomic,assign)NSInteger age;
    @property(nonatomic,copy)NSString *lesson;
    @property(nonatomic,copy)NSString *name;
    @end
    

    班级(Classes类),含有name(NSInteger),number(NSInteger),students(NSArray),teacher(Teacher)四个属性

    @interface Classes : NSObject
    @property(nonatomic,copy)NSString *name;
    @property(nonatomic,assign)NSInteger number;
    @property(nonatomic,strong)NSMutableArray *students;
    @property(nonatomic,strong)Teacher *teacher;
    @end
    

    注:
    1.解析数据中{}为字典,[]或()为数组
    2.无特殊情况,属性名与解析数据名称相同,遇到关键字除外
    3.存在数组,对象等属性时,在init方法中初始化

    (2) 获取数据
    1)与服务器交互,把下载路径写下来

    NSURL *url = [NSURL URLWithString:@"http://192.168.158.32/apple/JSONFile.json”];
    

    若为本地路径

    NSURL *url = [[NSURL alloc]initFileURLWithPath:@“/Users/apple/Desktop/test.txt”];
    

    2)获取数据,用二进制获取数据NSData

    NSData *data = [NSData dataWithContentsOfURL:url];
    

    3)序列化,将JSON最外层转化为字典

    NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
    

    options是NSJSONReadingOptions枚举值,可能的值有:
    **NSJSONReadingAllowFragments **生成字典和数组可变
    **NSJSONReadingMutableLeaves **生成的字符串可修改
    **NSJSONReadingAllowFragment **允许生成顶层对象非字典或数组

    3.解析数据

    (1)解析外层数据
    #define NFC(I) [NSString stringWithFormat:@"%@",I]

    NSString *classname = NFC([dic objectForKey:@"name"]);
    NSInteger classnumber = [[dic objectForKey:@"number"] integerValue];
    

    (2)将解析后的数据传给模型

    Classes *classes = [[Classes alloc]init];
    classes.name = classname;
    classes.number = classnumber;
    

    (3)解析学生,其对象为数组。使用循环逐层解析

    NSArray *stuarr = [dic objectForKey:@"students"];
    for (NSDictionary *studic in stuarr) {
        NSInteger stuage = [[studic objectForKey:@"age"] integerValue];
        NSInteger mark = [[studic objectForKey:@"mark"] integerValue];
        NSString *stuname = NFC([studic objectForKey:@"name"]);
    

    将数据传给模型

        Student *student = [[Student alloc]init];
        student.age = stuage;
        student.mark = mark;
        student.name = stuname;
        
        [classes.students addObject:student];
    }
    

    (4)解析讲师,其对象为Teacher对象,将其转换为字典继续解析

    NSDictionary *teacherdic = [dic objectForKey:@"teacher"];
    NSString *teachername = NFC([teacherdic objectForKey:@"name"]);
    NSString *lesson = NFC([teacherdic objectForKey:@"lesson"]);
    NSInteger teaage = [[teacherdic objectForKey:@"age"] integerValue];
    

    将数据传给模型

    Teacher *teacher = [[Teacher alloc]init];
    teacher.age = teaage;
    teacher.lesson = lesson;
    teacher.name = teachername;
    
    classes.teacher = teacher;
    

    注:
    1)建立模型对象时,随着解析而建,即需要建立到时候建立
    2)解析顺序,由上到下,由内到外

    二.XML解析

    两种方法,一种是第三方库,GData,用于XML格式的解析,第二种方法,是官方提供的一个方法。本文档使用第三方库操作。

    1.XML文档:
    标签/节点   <root></root>
    标签名     root
    

    【注】最上一级节点称为根节点

    <CityName>北京</CityName>
    标签值 北京

    <Item key="1" value="报纸"> </Item>
    属性: key="1"
    属性名: key
    属性值: "1"

    xml数据(文档)自上而下的树形结构
    <root>.....</root>(一个完整的节点),root节点的名称(标题) 中间的(....)为节点的内容
    每个xml文档只有一个根节点(树形结构中最外层的节点)
    xml文档(数据)由多个节点组成(根节点->子节点->子节点....)

    2.使用第三方库操作

    解析xml经常使用库: GData
    底层使用系统的libxml2库, 使用的时候添加libxml2

    (1)导入GData库
    (2)添加libxml二进制库
    Build Phases ---> Link Binary 添加 libxml2.dylib
    (3)设置头文件搜索路径
    Build Setting--->header search Paths
    双击后,点加号
    添加 /usr/include/libxml2
    //libxml2是系统库,需要到系统的目录下找到。
    (4)如果是arc的工程
    Build Phases ---> Compile Source File
    GDataXmlNode.m 禁止 ARC: -fno-objc-arc
    (5)添加“GDataXMLNode.h”文件到头文件中,如工程能编译通过,则说明GDataXMLNode添加成功

    3.解析xml

    (1)解析内容为

    <root>
    <name value="lucy">
        <age>26</age>
        <id>0001</id>
    </name>
    </root>
    

    (2)解析数据
    与服务器交互,建立模型,转换成二进制NSData与JSON解析相同。
    1)根据xml文档建立模型

    @interface Person : NSObject
    @property(nonatomic,copy)NSString *name;
    @property(nonatomic,copy)NSString *age;
    @property(nonatomic,copy)NSString *pID;
    @end
    

    2)与服务器交互

        NSURL *url = [NSURL URLWithString:@"http://192.168.158.32/apple/excise.xml"];
        NSData *data = [NSData dataWithContentsOfURL:url];
    

    3)把数据装换成xml

    GDataXMLDocument *doc = [[GDataXMLDocument alloc]initWithData:data options:GDataXMLInvalidKind error:&error];
    

    4)取根结点

    GDataXMLElement *arr = [doc rootElement];
    

    5)取出跟下面的所有子节点 第二层

    NSArray *names = [arr children];
    

    6)取出唯一的一个第二层的字节点 name结点

    GDataXMLElement *name = [names objectAtIndex:0];
    

    7)取出对应的属性

    NSString *nameValue = [[name attributeForName:@"value"] stringValue];
    

    8)取出name的字节点

    NSArray *ages = [name children];
    NSString *age = [[ages objectAtIndex:0] stringValue];
    NSArray *IDs = [name children];
    NSString *ID = [[IDs objectAtIndex:1] stringValue];
    

    9)把数据放到模型中

    Person *person = [[Person alloc]init];
    person.age = age;
    person.ID = ID;
    person.name = nameValue;
    

    :GDataXMLNode也能用于解析

    相关文章

      网友评论

      • zhaocarbon:层级深一些,这样解析还可以吗?SDK中提供的这个NSXMLParser适合一级XML解析,如果层级多了,使用这个类,解析起来很麻烦,并且得到处初始化此类,开发效率太低。

        建议使用NSXmlKit这个库,很简单高效!
        可以直接将XML转为NSDictionary!不必关心每层的数据深度!有多少层,全部给你转出来!非常高效!
        http://www.cocoachina.com/bbs/read.php?tid-1706071.html
      • zhaocarbon:层级深一些,这样解析还可以吗?SDK中提供的这个NSXMLParser适合一级XML解析,如果层级多了,使用这个类,解析起来很麻烦,并且得到处初始化此类,开发效率太低。

        建议使用NSXmlKit这个库,很简单高效!
        可以直接将XML转为NSDictionary!不必关心每层的数据深度!有多少层,全部给你转出来!非常高效!
        http://www.cocoachina.com/bbs/read.php?tid-1706071.html
        KeyLiu7: @民安主 写文章时xml解析只写了根据层级解析,实际工作中根据标签解析较多,我会把文章完善一下再更新,多谢指教。
      • 52343f143a92:写的挺好,赞!
      • 曾樑::+1::+1:
        KeyLiu7: @曾樑 谢谢支持

      本文标题:[程序员日记]OC中JSON解析与XML解析

      本文链接:https://www.haomeiwen.com/subject/uqdbhttx.html