美文网首页
iOS ---解析

iOS ---解析

作者: PlatonsDream | 来源:发表于2016-05-16 15:49 被阅读451次

    解析:从事先约定好的格式中提取数据。这种格式是前端开发人员和后台约定好的,约定获取的数据是什么格式的,就是用什么格式的解析方式(一般都是前端开发人员听从后台的)
    解析的前提:按照约定好的格式,数据提供方按照格式提供数据、数据获取方按照格式获取数据
    解析常见的为XML解析、 JSON解析

    JSON解析

    {
        "reason":"success",
        "result":[
            {
                "movieId":"216609",
                "movieName":"诡八楼",
                "pic_url":"http:\/\/v.juhe.cn\/movie\/picurl?2583083"
            },
            {
                "movieId":"216391",
                "movieName":"摩登森林之美食总动员",
                "pic_url":"http:\/\/v.juhe.cn\/movie\/picurl?2583246"
            },
            {
                "movieId":"216162",
                "movieName":"龟兔再跑",
                "pic_url":"http:\/\/v.juhe.cn\/movie\/picurl?2583181"
            }
             ......
           ],
    
    "error_code":0
    }
    

    上面为JSON格式数据,是一个大字典,字典的键值对中的值又包括数组。数组中又包含好多个字典,每个字典的键值对就是我们需要取出的数据
    json文件有两种结构:

    对象:"名称/值"对的集合。不同的语言中,它被理解为对象,记录,结构,字典,哈希表,有键列表,或者关联数组。以"{" 开始, 以"}" 结束, 是"名称/值"对的集合。名称和值中间用":"隔开。多个"名称/值"对之间用 ", " 隔开

    数组: 值得有序列表。在大部分语言中,它被理解为数组。以"[" 开始, 以"]" 结束,中间是数据。数据以 ", " 分隔

    JSON中的数据类型:字符串,数值,BOOL,对象,数组

    JSON解析工具:JSONKit、 NSJSONSerialization、 TouchJSON 和SBJSON等,其中NSJSONSerialization是系统提供的解析类,其解析效率是最高的
    其中关于其他第三方的JSON解析工具 在http://www.jianshu.com/p/a54d367adb2a 里面会有讲解,这里只是分享了系统自带的JSON解析工具NSJSONSerialization

    NSJSONSerialization 解析步骤:

    1.得到json文件,并且转换为data类型
    step1.1文件路径

    NSString *jsonPath = [[NSBundle mainBundle] pathForResource:@"MovieList" ofType:@"text"];
    

    step1.2转化为 nsdata类型

    NSData *jsonData = [NSData dataWithContentsOfFile:jsonPath];//根据路径获取data类型数据
    

    step1.3解析json 数据 jsonkit sbjson touchjson 三种解析第三方 但是还是系统提供的json解析更好用

    NSError *error = nil;
        NSDictionary *resultDic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragmentserror:&error];  //系统提供的json解析数据的工具
        //error错误  里面包含了解析是处的错误,一般打印是为了验证错误点
        NSLog(@"%@", error);
    

    2.判断解析获得的数据是否正常(是否是我们想要的数据) //这一步是在验证,真正开发时,可以不使用

    if (resultDic) {  //如果解析的数据不为空
            //判断当前的对象是否支持json格式
            if ([NSJSONSerialization isValidJSONObject:resultDic]) {
                NSData *strData = [NSJSONSerialization dataWithJSONObject:resultDic options:NSJSONWritingPrettyPrinted error:nil];
                //将data 转换为字符串
                if (strData != nil) {
                    NSString *str = [[NSString alloc] initWithData:strData encoding:NSUTF8StringEncoding];
                    NSLog(@"%@", str);
                }
            }
        }
    

    XML解析

    <?xml version="1.0" encoding="utf-8"?> <!--此行包含XML的版本信息和编码格式-->
    <students><!--这是开始标签,也就是根节点-->
        <student attribute = "七班班宝" position = "bu"><!--student为根节点的子节点,name节点的父节点, attribute是它的属性-->
            <name>赵威</name><!--李帅为name节点的值-->
            <sex>无</sex>
            <age>14</age>
        </student>
        <student attribute = "七班班长">
            <name>鹏鹏</name>
            <sex>随条件改变</sex>
            <age>17</age>
        </student>
        <student attribute = "banzhangtamei">
            <name>lisi</name>
            <sex>随他呢</sex>
            <age>33</age>
        </student>
    </students><!--节点的结束标签都是以/加标签名称组成 -->
    

    上面为XML格式数据。
    XML: Extensible Markup language (可拓展标记语言),主流数据格式之一,可以用来存储和传输数据
    节点:使用一对标签表示:起始和结束标签 <节点名> 数据或其他节点</节点名>
    XML数据结构:有且只有一个根节点,如上面代码中的students, 但是在根节点中可以嵌套好多子节点,子节点可以作为父节点嵌套下一级子节点 如<student> <name> </name> </student> student 作为父节点students的子节点,又是name节点的父节点
    节点中可以有值,存储在一对标签中 如 <name>赵威</name> 节点的值就是 赵威
    这样按照层级的层次把数据存储在节点中,获取数据也是调取节点中的数据

    XML解析的作用:数据交换 内容管理 用作配置文件

    XML解析又分为SAX解析和DOM解析

    XML解析之SAX解析

    SAX: Simple API for XML。基于事件驱动的解析方式,逐行进行解析数据(采用协议回调机制)。

    SAX解析使用的类:NSXMLParser 。NSXMLPraser是系统自带的XML解析类,采用SAX方式解析数据。
    解析过程由NSXMLPraserDelegate协议方法回调
    解析过程:开始标签->取值->结束标签->取值

    @interface RootViewController ()<NSXMLParserDelegate>//签协议
    @property (nonatomic, strong) NSMutableDictionary *dic;//用来student节点中的值
    @property (nonatomic ,strong) NSMutableArray *allDataArray;//用来盛放所有的student节点转换的字典
    @property (nonatomic, strong) NSMutableString *valueString;//用来拼接节点中间的值
    @end
    
    //得到需要解析的数据   获取数据文件所在的地址
        NSString *saxPath = [[NSBundle mainBundle] pathForResource:@"XMLDemo" ofType:@"xml"];
        //获取data
        NSData *saxData = [NSData dataWithContentsOfFile:saxPath];
        //创建sax解析的工具类对象
        NSXMLParser *saxParser = [[NSXMLParser alloc] initWithData:saxData];
        //指定代理
        saxParser.delegate = self;
        //开始解析 sax解析是一个同步的过程
       BOOL isParser = [saxParser parse];
        //判断解析成功
        if(isParser)
            NSLog(@"解析完成");
        else
            NSLog(@"解析失败");
    
    #pragma mark --sax解析代理方法
    //开始解析
    - (void)parserDidStartDocument:(NSXMLParser *)parser {
         NSLog(@"开始解析");
        //初始化数组(遍历构造器)   在开始解析里面初始化保存数据的数组
        self.allDataArray = [NSMutableArray array];
    }
    
    //开始解析某个节点
    /*
    elementName:标签名称
    namespaceURI:命名空间指向的链接
    qualifiedName:命名空间的名称
    attributtes:节点的所有属性(可以多个)
     */
    - (void)parser:(NSXMLParser *)parser didStartElement:(nonnull NSString *)elementName namespaceURI:(nullable NSString *)namespaceURI qualifiedName:(nullable NSString *)qName attributes:(nonnull NSDictionary<NSString *,NSString *> *)attributeDict {
        NSLog(@"开始解析%@节点", elementName);
        //当开始解析student子节点的时候,就应该初始化字典,因为一个字典就对应着一个学生的信息
        //每解析一个student,就初始化一次
        if ([elementName isEqualToString:@"student"]) {
            self.dic = [NSMutableDictionary dictionary];
        }
    }
    
    //获取节点之间的值
    - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
        NSLog(@"取值---%@", string);
    //    if(self.valueString){//说明有值
    //        [self.valueString appendString:string];
    //    }else{
    //        self.valueString = [NSMutableString stringWithString:string];
    //    }
        //这里会把空格覆盖掉
        if (string != nil) {
            self.valueString = [NSMutableString stringWithString:string];
        }
        
    }
    
    //某个节点结束取值
    - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
        NSLog(@"结束%@节点的解析", elementName);
        
        if ([elementName isEqualToString:@"name"]) {//说明name节点已经取值结束
            [self.dic setObject:self.valueString forKey:elementName];
        }
        if ([elementName isEqualToString:@"age"]) {
            [self.dic setObject:self.valueString forKey:elementName];
        }
        if ([elementName isEqualToString:@"sex"]) {
            [self.dic setObject:self.valueString forKey:elementName];
        }
        
    //    [self.dic setObject:self.valueString forKey:elementName];
        
        if ([elementName isEqualToString:@"student"]) {//一个student已经解析完毕
            [self.allDataArray addObject:self.dic]; //把studnet的字典添加到数组中
        }
        self.valueString = nil; 
    }
    
    //结束解析 在结束解析协议方法中内获取全部的数据
    - (void)parserDidEndDocument:(NSXMLParser *)parser {
        //就可以使用解析完成的数据
        NSLog(@"%@", self.allDataArray);
        NSLog(@"整个解析结束");
    }
    
    //报告不可恢复的解析错误
    - (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
        NSLog(@"解析出现错误:%@", parseError);
    }
    

    XML解析之DOM解析

    DOM: Document Object Model(文档对象类型)。DOM方式解析XML时,读入整个XML文档并构建一个驻留内存的树结构(节点数),通过遍历节点树结构可以检索任意XML节点,读取他的属性和值。而且通常情况下,可以借助XPath,直接查询XML节点。
    DOM是基于文档的解析方式。

    DOM解析需要导入的库 libxml2.dylib(ios7之后改为libxml2.tdb) GDataXMLNode
    GDataXMLNode是Google提供的开元XML解析类,对libxml2.tdb进行了Object-C的封装,能对较小或中等的xml文档进行读写操作并且支持XPath语法
    使用GDataXMLNode使用方法
    1.获取GDataXMLNode.h/m文件,将GDataXMLNode.h/m文件添加到工程中
    2.向工程中增加"libxml2.dylib(ios7之后改为libxml2.tdb) "动态库
    3.在工程的"Build Settings"页中找到"Header Search Path"项,添加/usr/include/libxml2
    4.导入"GDataXMLNode.h"文件到头文件中,如工程能编译通过,则说明GDataXMLNode添加成功

    解析过程

    //用来盛放所有的字典
        NSMutableArray *datasourse = [NSMutableArray array];
        
        //得到需要解析的数据(xml文件)
        NSString *xmlPath = [[NSBundle mainBundle] pathForResource:@"XMLDemo" ofType:@"xml"];
        //转换为NSData类型
        NSData *xmlData = [NSData dataWithContentsOfFile:xmlPath];
        
        //构建document文档对象
        NSError *error = nil;
        GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:xmlData options:0 error:&error];//options:的值为0,这个是预留的
        
        //找到根节点,就是students
        GDataXMLElement *rootElement = [doc rootElement];
        
        //找到根节点的所有子节点,就是所有的student
        NSArray *allSubNotes = [rootElement elementsForName:@"student"];
        //找到student节点的所有子节点
        for (GDataXMLElement *item in allSubNotes) {
            //每次循环开始的时候,说明是一个新的student节点,我们需要字典来盛放他所有的值
            //防止引用计数加一,使用初始化方法
            
            NSLog(@"%@", item.attributes[0]);
            NSMutableDictionary *studentDic = [NSMutableDictionary dictionary];
            
            //得到name节点
            NSArray *nameArray = [item elementsForName:@"name"];
    //        GDataXMLElement *nameElement = [nameArray objectAtIndex:0];
            GDataXMLElement *nameElement = [nameArray firstObject];
            //取值
            NSString *name = [nameElement stringValue];
            [studentDic setObject:name forKey:@"name"];
            //取出sex
            NSArray *sexArray = [item elementsForName:@"sex"];
            GDataXMLElement *sexElement = [sexArray firstObject];
            NSString *sex = [sexElement stringValue];
            [studentDic setObject:sex forKey:@"sex"];
            
            //取出age
            NSArray *ageArray = [item elementsForName:@"age"];
            GDataXMLElement *ageElement = [ageArray firstObject];
            //取值
            NSString *age = [ageElement stringValue];
            [studentDic setObject:age forKey:@"age"];
            
            //将字典添加到可变数组中
            [datasourse addObject:studentDic];
        }
    

    SAX解析和DOM解析的区别:

    SAX只能读不能写,DOM解析不知能读,还能写(增加节点)
    如果文档小一些,DOM解析效率更高一些
    DOM解析基于文档,SAX解析基于事件
    如果数据量相同时,DOM解析效率更高
    SAX解析是逐行解析,DOM解析是整个文档来操作的
    数据量比较大时,适用于SAX解析

    JSON解析和DOM解析的优缺点

    XML优缺点

    优点:

    1.格式统一,符合标准
    2.容易与其他系统进行远程交互,数据共享比较方便

    缺点:

    1.XML格式文件庞大,格式复杂,传输暂用宽带
    2.服务器端和客户端都需要花费大量代码来维护XML,不论服务器端还是客户端都使代码变得异常复杂和不容易维护
    3.刻画段不同浏览器之间解析XML的方式不一致,需要重复编写很多代码
    4.服务器端和客户端解析MXL花费资源和时间

    JSON优缺点
    优点:

    1.数据格式比较简单,易于读写,格式都是压缩的,占用带宽小。
    2.易于解析这种语言。
    3.支持多种语言,包括ActionScrip, C, C#, ColdFusion, Java, JavaScript, Perl, PHP, Python, Ruby等语言服务器端语言,便于服务器端的解析
    4.因为JSON格式能够直接为服务器端代码使用,大大简化了服务器端和客户端的代码开发量,大师完成的任务不变,且易于维护。

    缺点:

    1.没有XML格式这么推广的深入人心和使用广泛,没有XML那么通用性。
    2.JSON格式目前在Web Service中推广还属于初级阶段

    比较 :

    xml在布局文件比json强太多,但是json更便于传输
    xml是可拓展的语言,随便往里面添加标签,标签名字可以随便改变

    相关文章

      网友评论

          本文标题:iOS ---解析

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