XML和JSON的对比

简介:

  客户端和服务器之间进行数据交互时,服务器往往会返回给客户端一定格式的数据。一般而言,服务器返回给客户端的数据为JSON或者XML文档格式的数据(文件下载除外)。下面就针对于这两种数据格式分别介绍。

(一)JSON数据解析:

特点:

  JSON来自民间,是一种轻量级的数据格式。 特点是:体积小,传输快,所以百分之八十的数据都是用JSON格式。

格式:

  JSON的格式很像OC中的字典和数组,例如:

{"name" : "jack", "age" : 10}
{"names" : ["jack", "rose", "jim"]}

JSON – OC 转换对照表
----------------JSON-------------- ------------------OC------------------
------------大括号 { }------------- -------- --NSDictionary@{}---------
------------中括号 [ ]-------------- -------------NSArray@[]-------------
------------双引号 " "-------------- -------------NSString@""------------
------ ---数字 10、10.8----------- -------NSNumber@10、@10.8------

 

 

 

 

 

需要注意的几点:

  1.标准格式的JSON:key必须用双引号

  2.true/false转换成OC数据后是NSNumber类型。true-->@1;false-->@0

  3.null-->NSNull(空对象)

验证方法:

// 字符串
NSString *json = @"null";
// 字符串->二进制数据
NSData *data = [json dataUsingEncoding:NSUTF8StringEncoding];
// 二进制数据->JSON数据
     id obj = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
     NSLog(@"%@", [obj class]);
/*
   打印结果: 
   2015-08-28 00:23:04.393 JSON和OC对象相互转换[6274:345722] NSNull
*/

JSON数据解析方案:

  在iOS中,JSON的常见解析方案有4种,这4种解析方案可以分为两类。

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

  第二类:苹果原生(自带):NSJSONSerialization(性能最好)

NSJSONSerialization的常见两个方法:

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

// JSON数据 -> OC对象
+ (id)JSONObjectWithData:(NSData *)data options:(NSJSONReadingOptions)opt error:(NSError **)error;
  • NSJSONReadingOptions
    • NSJSONReadingMutableContainers = (1UL << 0)
      • 创建出来的数组和字典就是可变
    • NSJSONReadingMutableLeaves = (1UL << 1)
      • 数组或者字典里面的字符串是可变的, iOS7以后无效
    • NSJSONReadingAllowFragments
      • 允许解析出来的对象不是字典或者数组,比如直接是字符串或者NSNumber

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

// OC对象 ->JSON数据 
+ (NSData *)dataWithJSONObject:(id)obj options:(NSJSONWritingOptions)opt error:(NSError **)error;

JSON在线解析地址:

http://tool.oschina.net/codeformat/json

http://json.parser.online.fr/

复杂JSON数据解析:

    // 用模型的的ID接收字典中的key为id的value(需要导入MJExtension)
    [WSVideos setupReplacedKeyFromPropertyName:^NSDictionary *{
        return @{@"ID":@"id"};
    }];
    
    // 1.创建URL
    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/video?type=JSON"];
    // 2.根据URL创建请求
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    // 3.利用NSURLConnection发送
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
        if (!data) {
            
            [self.tableView reloadData];
            
        }else{
                // 把json数据解析成oc数据
                id res = [NSJSONSerialization  JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
                NSLog(@"%@",res);
                
                if ([res isKindOfClass:[NSArray class]]) {
                    NSLog(@"array");
                }else if ([res isKindOfClass:[NSDictionary class]]) {
                    NSLog(@"dict");
                    
                    // 把oc数据转换成数据模型
                    // 把数据模型保存到模型数组
                    self.videos = [WSVideos objectArrayWithKeyValuesArray:res[@"videos"]];
                }
                
                // 刷新表格(发送异步请求,拿到数据后一定要刷新表格)
                [self.tableView reloadData];
            }
        }];


(二)XML数据解析:

  全称是Extensible Markup Language,译作“可扩展标记语言”。一般也叫XML文档(XML Document)。

特点:

--

格式:

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

1.XML语法 – 文档声明:

在XML文档的最前面,必须编写一个文档声明,用来声明XML文档的类型
最简单的声明
<?xml version="1.0" ?>
用encoding属性说明文档的字符编码
<?xml version="1.0" encoding="UTF-8" ?>

2.XML语法 – 元素(Element)

一个元素包括了开始标签和结束标签
拥有内容的元素:<video>小黄人</video>
没有内容的元素:<video></video>
没有内容的元素简写:<video/>

一个元素可以嵌套若干个子元素(不能出现交叉嵌套)例如:
<videos>
    <video>
        <name>小黄人 第01部</name>
             <length>30</length>
    </video>
</videos>

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

3.XML语法 – 属性(Attribute)

一个元素可以拥有多个属性
<video name="小黄人 第01部" length="30" />
video元素拥有name和length两个属性
属性值必须用 双引号"" 或者 单引号'' 括住

实际上,属性表示的信息也可以用子元素来表示,比如
<video>
    <name>卑鄙的我 第01部</name>
        <length>30</length>
</video>

注意:XML语法 –元素的注意

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

第2个
<video>
    小黄人
</video>

XML数据解析方案:

  在iOS中,XML的解析方式有2种,分别是SAX和DOM解析。

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

  解析手段大致分为两类,苹果原生/自带的解析器和第三方框架。

第一类:苹果原生。NSXMLParserSAX方式解析,使用简单

第二类:第三方框架。libxml2:纯C语言,默认包含在iOS SDK中,同时支持DOM和SAX方式解析
          GDataXMLDOM方式解析,由Google开发,基于libxml2

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

因为libxml2是纯C语言的,使用难度大,所以不建议使用。GDataXML是谷歌研发的,解析的特点是一次性将整个XML文档加载进内存,所以不适合大文件的解析。综上所分析,只有苹果自带的NSXMLParser是最常用的。

NSXMLParser使用(SAX方式解析):

特点:

NSXMLParser采取的是SAX方式解析,特点是事件驱动,下面情况都会通知代理
当扫描到文档(Document)的开始与结束
当扫描到元素(Element)的开始与结束

步骤:

    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/video?type=XML"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
        
        // 1.根据需要解析的XML数据, 创建NSXMLParser对象
        NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
        
        // 2.设置代理, 通过代理方法告诉NSXMLParser, 需要获取哪些元素和哪些属性
        parser.delegate = self;
        
        // 2.开始解析
        [parser parse];
        
    }];

代理方法:

// 只要开始解析XML文档就会调用
- (void)parserDidStartDocument:(NSXMLParser *)parser
{

}
// 只要解析完毕XML文档就会调用
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
    // 刷新UI
    [self.tableView reloadData];
}
// 只要开始解析一个元素就会调用
// elementName : 元素名称
// attributeDict : 元素中的属性
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
    
    if ([elementName isEqualToString:@"videos"]) {
        return;
    }
    XMGVideo *video = [XMGVideo objectWithKeyValues:attributeDict];
    [self.videos addObject:video];
}

// 只要解析完一个元素就会调用
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{

}
// 解析出现错误时调用
- (void)parser:(NSXMLParser *)parser validationErrorOccurred:(NSError *)validationError
{
    NSLog(@"error");
}

GDataXML使用(DOM方式解析):

配置步骤:

  1.导入GDataXML框架,导入libxml2库(iOS8不需要导入)

  2.设置libxml2的头文件搜索路径(为了能找到libxml2库的所有头文件)

    在Head Search Path中加入/usr/include/libxml2
  3.设置链接参数(自动链接libxml2库)

    在Other Linker Flags中加入-lxml2
  4.由于GDataXML是非ARC的,因此得设置编译参数
    

使用步骤:

GDataXML中常用的类
GDataXMLDocument:代表整个XML文档

GDataXMLElement:代表文档中的每个元素
使用attributeForName:方法可以获得属性值    

    // 1、创建URL
    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/video?type=XML"];
    // 2、根据URL创建请求
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    // 3、利用NSURLConnection发送请求
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
        
        // 1.创建解析器
        GDataXMLDocument *document = [[GDataXMLDocument alloc] initWithData:data options:kNilOptions error:nil];
        // 2.获取XML文档的根元素
        GDataXMLElement *rootElement = document.rootElement;
        // 3.获取根元素下的所有子元素
        NSArray *allSubElement = [rootElement elementsForName:@"video"];
        // 4.遍历子元素,取出属性,转换为模型
        for (GDataXMLElement *element in allSubElement) {
            WSVideos *video = [[WSVideos alloc] init];
            
            video.name = [element attributeForName:@"name"].stringValue;
            video.ID = @([element attributeForName:@"id"].stringValue.integerValue);
            video.length = @([element attributeForName:@"length"].stringValue.integerValue);
            video.image = [element attributeForName:@"image"].stringValue;
            video.url = [element attributeForName:@"url"].stringValue;
            
            [self.videos addObject:video];
        }
        // 刷新表格
        [self.tableView reloadData];
        
    }];

 

posted @ 2015-08-28 01:54  oneSong  阅读(496)  评论(0编辑  收藏  举报