JSON&XML

JSON解析

JSON简单介绍

  • 什么是JSON
    • JSON是一种轻量级的数据格式,一般用于数据交互
    • 服务器返回给客户端的数据,一般都是JSON格式或者XML格式(文件下载除外)
  • 相关说明
    • JSON的格式很像OC中的字典和数组

    • 标准JSON格式key必须是双引号

  • JSON解析方案
    • 第三方框架 JSONKit\SBJSON\TouchJSON
    • 苹果原生(NSJSONSerialization)

JSON解析相关代码

json数据->OC对象


//把json数据转换为OC对象

-(void)jsonToOC

{

    //1. 确定url路径

    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=33&pwd=33&type=JSON"];

    //2.创建一个请求对象

    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    //3.使用NSURLSession发送一个异步请求

    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {

        //4.当接收到服务器响应的数据后,解析数据(JSON--->OC)

        /*

         第一个参数:要解析的JSON数据,是NSData类型也就是二进制数据

         第二个参数: 解析JSON的可选配置参数

         NSJSONReadingMutableContainers 解析出来的字典和数组是可变的

         NSJSONReadingMutableLeaves 解析出来的对象中的字符串是可变的  iOS7以后有问题

         NSJSONReadingAllowFragments 被解析的JSON数据如果既不是字典也不是数组, 那么就必须使用这个

         */

        NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];

        NSLog(@"%@",dict);

    }];

}

OC对象->JSON对象


 //1.要转换成JSON数据的OC对象*这里是一个字典

    NSDictionary *dictM = @{

                            @"name":@"wendingding",

                            @"age":@100,

                            @"height":@1.72

                            };

    //2.OC->JSON

    /*

     注意:可以通过+ (BOOL)isValidJSONObject:(id)obj;方法判断当前OC对象能否转换为JSON数据

     具体限制:

         1.obj 是NSArray 或 NSDictionay 以及他们派生出来的子类

         2.obj 包含的所有对象是NSString,NSNumber,NSArray,NSDictionary 或NSNull

         3.字典中所有的key必须是NSString类型的

         4.NSNumber的对象不能是NaN或无穷大

     */

    /*

     第一个参数:要转换成JSON数据的OC对象,这里为一个字典

     第二个参数:NSJSONWritingPrettyPrinted对转换之后的JSON对象进行排版,无意义

     */

    NSData *data = [NSJSONSerialization dataWithJSONObject:dictM options:NSJSONWritingPrettyPrinted error:nil];

    //3.打印查看Data是否有值

    /*

     第一个参数:要转换为STring的二进制数据

     第二个参数:编码方式,通常采用NSUTF8StringEncoding

     */

    NSString *strM = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];

    NSLog(@"%@",strM);

OC对象和JSON数据格式之间的一一对应关系


//OC对象和JSON数据之间的一一对应关系

-(void)oCWithJSON

{

    //JSON的各种数据格式

    //NSString *test = @"\"wendingding\"";

    //NSString *test = @"true";

    NSString *test = @"{\"name\":\"wendingding\"}";

    //把JSON数据->OC对象,以便查看他们之间的一一对应关系

    //注意点:如何被解析的JSON数据如果既不是字典也不是数组(比如是NSString), 那么就必须使用这NSJSONReadingAllowFragments

    id obj = [NSJSONSerialization JSONObjectWithData:[test dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:nil];

    NSLog(@"%@", [obj class]);

    /* JSON数据格式和OC对象的一一对应关系

         {} -> 字典

         [] -> 数组

         "" -> 字符串

         10/10.1 -> NSNumber

         true/false -> NSNumber

         null -> NSNull

     */

}

}

如何查看复杂的JSON数据

方法一:

在线格式化http://tool.oschina.net/codeformat/json

方法二:

把解析后的数据写plist文件,通过plist文件可以直观的查看JSON的层次结构。

[dictM writeToFile:@"/Users/文顶顶/Desktop/videos.plist" atomically:YES];

字典转模型框架

  • 相关框架

a.Mantle 需要继承自MTModel

 b.JSONModel 需要继承自JSONModel

 c.MJExtension 不需要继承,无代码侵入性
  • MJExtension框架的简单使用

//1.把字典数组转换为模型数组

    //使用MJExtension框架进行字典转模型

        self.videos = [XMGVideo objectArrayWithKeyValuesArray:videoArray];

//2.重命名模型属性的名称

//第一种重命名属性名称的方法,有一定的代码侵入性

//设置字典中的id被模型中的ID替换

+(NSDictionary *)replacedKeyFromPropertyName

{

    return @{

             @"ID":@"id"

             };

}

//第二种重命名属性名称的方法,代码侵入性为零

    [XMGVideo setupReplacedKeyFromPropertyName:^NSDictionary *{

        return @{

                 @"ID":@"id"

                 };

    }];

//3.MJExtension框架内部实现原理-运行时

XML解析

XML简单介绍

  • XML:可扩展标记语言

    a.语法

    b.XML文档的三部分(声明、元素和属性)
    
    c.其它注意点(注意不能交叉包含、空行换行、XML文档只能有一个根元素等)
    

XML解析

  • XML解析的两种方式
> 001 SAX:从根元素开始,按顺序一个元素一个元素的往下解析,可用于解析大、小文件

002 DOM:一次性将整个XML文档加载到内存中,适合较小的文件
  • 解析XML的工具

001 苹果原生NSXMLParser:使用SAX方式解析,使用简单

 002 第三方框架

            libxml2:纯C语言的,默认包含在iOS SDK中,同时支持DOM和SAX的方式解析

            GDataXML:采用DOM方式解析,该框架由Goole开发,是基于xml2的

XML解析实现

NSXMLParser

  • 使用NSXMLParser解析XML步骤和代理方法

//解析步骤:

//4.1 创建一个解析器

NSXMLParser *parser = [[NSXMLParser alloc]initWithData:data];

//4.2 设置代理

parser.delegate = self;

//4.3 开始解析

[parser parse];

-----------------------------------------

//1.开始解析XML文档

-(void)parserDidStartDocument:(nonnull NSXMLParser *)parser

//2.开始解析XML中某个元素的时候调用,比如

-(void)parser:(nonnull NSXMLParser *)parser didEndElement:(nonnull NSString *)elementName namespaceURI:(nullable NSString *)namespaceURI qualifiedName:(nullable NSString *)qName

//4.XML文档解析结束

-(void)parserDidEndDocument:(nonnull NSXMLParser *)parser

GDataParser

  • 使用GDataParser解析XML的步骤和方法

//4.0 配置环境

// 001 先导入框架,然后按照框架使用注释配置环境

// 002 GDataXML框架是MRC的,所以还需要告诉编译器以MRC的方式处理GDataXML的代码

//4.1 加载XML文档(使用的是DOM的方式一口气把整个XML文档都吞下)

    GDataXMLDocument *doc = [[GDataXMLDocument alloc]initWithData:data options:kNilOptions error:nil];

//4.2 获取XML文档的根元素,根据根元素取出XML中的每个子元素

  NSArray * elements = [doc.rootElement elementsForName:@"video"];

//4.3 取出每个子元素的属性并转换为模型

for (GDataXMLElement *ele in elements) {

    XMGVideo *video = [[XMGVideo alloc]init];

    video.name = [ele attributeForName:@"name"].stringValue;

    video.length = [ele attributeForName:@"length"].stringValue.integerValue;

    video.url = [ele attributeForName:@"url"].stringValue;

    video.image = [ele attributeForName:@"image"].stringValue;

    video.ID = [ele attributeForName:@"id"].stringValue;

    //4.4 把转换好的模型添加到tableView的数据源self.videos数组中

    [self.videos addObject:video];

}

多值参数和中文输出问题

多值参数如何设置请求路径


//多值参数

/*

 如果一个参数对应着多个值,那么直接按照"参数=值&参数=值"的方式拼接

 */

-(void)test

{

    //1.确定URL

    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/weather?place=Beijing&place=Guangzhou"];

    //2.创建请求对象

    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    //3.发送请求

    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {

        //4.解析

        NSLog(@"%@",[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]);

    }];

}

如何解决字典和数组中输出乱码的问题

  • 给字典和数组添加一个分类,重写descriptionWithLocale方法,在该方法中拼接元素格式化输出。

-(nonnull NSString *)descriptionWithLocale:(nullable id)locale

代码实现


// 只需创建.m文件即可

//  Foundation+Log.m

//  多值参数和中文输出

#import 

@implementation NSDictionary (Log)

//重写系统的方法控制输出

-(NSString *)descriptionWithLocale:(id)locale indent:(NSUInteger)level

{

//    return @"你大爷是你大姐";

    NSMutableString *string = [NSMutableString string];

    

    //{}

    [string appendString:@"{"];

    

    //拼接key--value

    [self enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {

        [string appendFormat:@"%@:",key];

        [string appendFormat:@"%@,",obj];

        

    }];

    [string appendString:@"}"];

    

    //删除逗号

    //从后往前搜索 得到的是搜索到的第一个符号的位置

    NSRange range = [string rangeOfString:@"," options:NSBackwardsSearch];

    if (range.location != NSNotFound) {

        [string deleteCharactersInRange:range];

    }

    

    return string;

}

@end

@implementation NSArray (Log)

//重写系统的方法控制输出

-(NSString *)descriptionWithLocale:(id)locale indent:(NSUInteger)level

{

    //    return @"你大爷是你大姐";

    NSMutableString *string = [NSMutableString string];

    

    //{}

    [string appendString:@"["];

    

    //拼接obj

    [self enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {

        [string appendFormat:@"%@,\n",obj];

    }];

    [string appendString:@"]"];

    

    //删除逗号

    //从后往前搜索 得到的是搜索到的第一个符号的位置

    NSRange range = [string rangeOfString:@"," options:NSBackwardsSearch];

    if (range.location != NSNotFound) {

        [string deleteCharactersInRange:range];

    }

    return string;

}

@end

你可能感兴趣的:(JSON&XML)