05.iOS JSON,XML数据解析

@(〓〓 iOS-实用技术)[JSON/XML 数据解析]


目录

  • 05.iOS JSON,XML数据解析
  • 1.JSON数据解析
    • 1.1 NSJSONSerialization解析
    • 1.2 JSONKit解析
    • 1.3 SBJson解析
    • 1.4 TouchJSon解析
  • 2.XML数据解析
    • 2.1 NSXMLParser代理方式解析XML数据
    • 2.2 GDataXML解析XML
      • 使用GDataXML框架设置步骤,具体步骤看截图
      • 使用Google的GDataXML框架解析XML

1.JSON数据解析

本文JSON数据解析将介绍TouchJson、SBJson 、JSONKit和iOS5所支持的原生的json方法,解析国家气象局API,TouchJson和SBJson需要下载他们的库.

  • 国家气象局提供的天气预报接口

接口地址有两个:
http://www.weather.com.cn/data/sk/101010100.html
http://www.weather.com.cn/data/cityinfo/101010100.html

  • 四种JSON解析方式效率

解析速度由高到低: NSJSONSerialization -> JSONKit -> SBJson -> TouchJSon


1.1 NSJSONSerialization解析

  • 1.使用IOS5自带解析类NSJSONSerialization方法解析
- (IBAction)btnPressIOS5Json:(id)sender {  

    NSError *error;  
    //加载一个NSURL对象  
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://m.weather.com.cn/data/101180601.html"]];  
    //将请求的url数据放到NSData对象中  
    NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];  
    //IOS5自带解析类NSJSONSerialization从response中解析出数据放到字典中  
    NSDictionary *weatherDic = [NSJSONSerialization JSONObjectWithData:response options:NSJSONReadingMutableLeaves error:&error];  
    NSDictionary *weatherInfo = [weatherDic objectForKey:@"weatherinfo"];  
    txtView.text = [NSString stringWithFormat:@"今天是 %@  %@  %@  的天气状况是:%@  %@ ",[weatherInfo objectForKey:@"date_y"],[weatherInfo objectForKey:@"week"],[weatherInfo objectForKey:@"city"], [weatherInfo objectForKey:@"weather1"], [weatherInfo objectForKey:@"temp1"]];  
    NSLog(@"weatherInfo字典里面的内容为--》%@", weatherDic );  

}  

1.2 JSONKit解析

  • 1.使用JSONKit的解析方法:(需导入包:#import "JSONKit/JSONKit.h")
- (IBAction)btnPressJsonKit:(id)sender {  
      
    //如果json是“单层”的,即value都是字符串、数字,可以使用objectFromJSONString  
    NSString *json1 = @"{\"a\":123, \"b\":\"abc\"}";  
    NSLog(@"json1:%@",json1);  
    NSDictionary *data1 = [json1 objectFromJSONString];  
    NSLog(@"json1.a:%@",[data1 objectForKey:@"a"]);  
    NSLog(@"json1.b:%@",[data1 objectForKey:@"b"]);  
    [json1 release];  
    
    //如果json有嵌套,即value里有array、object,如果再使用objectFromJSONString,程序可能会报错(测试结果表明:使用由网络或得到的php/json_encode生成的json时会报错,但使用NSString定义的json字符串时,解析成功),最好使用objectFromJSONStringWithParseOptions:  
    NSString *json2 = @"{\"a\":123, \"b\":\"abc\", \"c\":[456, \"hello\"], \"d\":{\"name\":\"张三\", \"age\":\"32\"}}";  
    NSLog(@"json2:%@", json2);  
    NSDictionary *data2 = [json2 objectFromJSONStringWithParseOptions:JKParseOptionLooseUnicode];  
    NSLog(@"json2.c:%@", [data2 objectForKey:@"c"]);  
    NSLog(@"json2.d:%@", [data2 objectForKey:@"d"]);  
    [json2 release];  

} 

1.3 SBJson解析

  • 1.使用SBJson解析方法:(需导入包:#import "SBJson/SBJson.h")
//使用SBJson解析南阳的天气  
- (IBAction)btnPressSBJson:(id)sender {  

    NSURL *url = [NSURL URLWithString:@"http://m.weather.com.cn/data/101180701.html"];  
    NSError *error = nil;  
    NSString *jsonString = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error];  
    SBJsonParser *parser = [[SBJsonParser alloc] init];  
    
    NSDictionary *rootDic = [parser objectWithString:jsonString error:&error];  
    NSDictionary *weatherInfo = [rootDic objectForKey:@"weatherinfo"];  
    txtView.text = [NSString stringWithFormat:@"今天是 %@  %@  %@  的天气状况是:%@  %@ ",[weatherInfo objectForKey:@"date_y"],[weatherInfo objectForKey:@"week"],[weatherInfo objectForKey:@"city"], [weatherInfo objectForKey:@"weather1"], [weatherInfo objectForKey:@"temp1"]];  

}  

1.4 TouchJSon解析

  • 1.使用TouchJSon解析方法:(需导入包:#import "TouchJson/JSON/CJSONDeserializer.h")
//使用TouchJson来解析北京的天气  
- (IBAction)btnPressTouchJson:(id)sender {  

    //获取API接口  
    NSURL *url = [NSURL URLWithString:@"http://m.weather.com.cn/data/101010100.html"];  
    //定义一个NSError对象,用于捕获错误信息  
    NSError *error;  
    NSString *jsonString = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error];  
    NSLog(@"jsonString--->%@",jsonString);  
    
    //将解析得到的内容存放字典中,编码格式为UTF8,防止取值的时候发生乱码  
    NSDictionary *rootDic = [[CJSONDeserializer deserializer] deserialize:[jsonString dataUsingEncoding:NSUTF8StringEncoding] error:&error];  
    //因为返回的Json文件有两层,去第二层内容放到字典中去  
    NSDictionary *weatherInfo = [rootDic objectForKey:@"weatherinfo"];  
    NSLog(@"weatherInfo--->%@",weatherInfo);  
    //取值打印  
    txtView.text = [NSString stringWithFormat:@"今天是 %@  %@  %@  的天气状况是:%@  %@ ",[weatherInfo objectForKey:@"date_y"],[weatherInfo objectForKey:@"week"],[weatherInfo objectForKey:@"city"], [weatherInfo objectForKey:@"weather1"], [weatherInfo objectForKey:@"temp1"]];  
      
}  

2.XML数据解析

2.1 NSXMLParser代理方式解析XML数据

  • 1.NSXMLParser常用代理方法
#pragma mark - 
// SINGLE: 当开始解析XML文档的时候调用,只调用一次
- (void)parserDidStartDocument:(NSXMLParser *)parser;

// SINGLE: 开始解析某个元素的时候调用,如果有多个元素,会调用多次,调用一次解析一个元素
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict;

// SINGLE: 结束解析某个元素的时候调用,会调用多次
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName;

// SINGLE: 整个XML文档解析结束的时候调用
- (void)parserDidEndDocument:(NSXMLParser *)parser;
  • 2.使用NSXMLParser解析XML数据
    • 开启XML数据解析 [parser parse];
// REMARKS: 解析XML数据,使用NSXMLParser代理方式解析XML数据
- (void)netWork
{
    // 创建请求数据的url路径,XML格式的数据
    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/video?type=XML"];
    
    // 创建请求对象
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    
    // 发送GET请求,异步
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
        
        // REMARKS: 解析XML数据,使用NSXMLParser代理方式解析XML数据
        NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
        
        // 设置代理
        parser.delegate = self;
        
        // SINGLE: 开始解析 该方式是阻塞的
        [parser parse];
        
        // 刷新tableView数据
        [self.tableView reloadData];
        
    }];
}

#pragma mark - 
// SINGLE: 当开始解析XML文档的时候调用,只调用一次
- (void)parserDidStartDocument:(NSXMLParser *)parser
{
    NSLog(@"parserDidStartDocument");
}

// SINGLE: 开始解析某个元素的时候调用,如果有多个元素,会调用多次,调用一次解析一个元素
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
//    NSLog(@"didStartElement: %@ --- %@", elementName, attributeDict);
    
    // SINGLE: 通过以上打印结果观察,服务器返回的数据中,key为videos的元素(根元素)是数组,所以不能将其添加到数据源数组中,只能添加数组中的元素
    if ([elementName isEqualToString:@"videos"]) {
        return ;
    }
    
    // SINGLE: 使用MJExtension框架将attributeDict字典转模型,
    WXVideo *video = [[WXVideo alloc] init];
    [video mj_setKeyValues:attributeDict];
    [self.videos addObject:video];
}

// SINGLE: 结束解析某个元素的时候调用,会调用多次
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
//    NSLog(@"didEndElement --- %@", elementName);
}

// SINGLE: 整个XML文档解析结束的时候调用
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
    NSLog(@"parserDidEndDocument");
}

2.2 GDataXML解析XML

使用GDataXML框架设置步骤,具体步骤看截图

  • 使用GDataXML框架解析XML文件时,编译错误解决方案'libxml/tree.h' file not found
05.iOS JSON,XML数据解析_第1张图片
01.GDataXML编译错误解决方案.png

  • 设置GDataXML的编译环境为非ARC环境
05.iOS JSON,XML数据解析_第2张图片
02.GDataXML的编译环境为非ARC环境.png

  • 设置Other Linker Flags,添加一项 -lxml2
05.iOS JSON,XML数据解析_第3张图片
03.Other Linker Flags,添加一项 -lxml2.png

使用Google的GDataXML框架解析XML

  • 1.使用Google的GDataXML框架解析XML,用GDataXML框架解析XML数据,GDataXML会一次性把整个XML加载到内存,内存短时间内会增大,如果XML数据量大不推荐使用
// 一次性加载整个XML文档
GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:data options:kNilOptions error:nil];

  • 2.GDataXML框架解析XML

    • 获取XML的根元素,拿到所有名称叫做video的子元素,该例子的XML根元素为数组,所以用数组接收.

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

// REMARKS: GET方法异步请求cell数据
- (void)netWork
{
    // 创建请求数据的url路径,XML格式的数据
    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/video?type=XML"];
    
    // 创建请求对象
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    
    // 发送GET请求,异步
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
        
        // REMARKS: 使用Google的GDataXML框架解析XML,用GDataXML框架解析XML数据,GDataXML会一次性把整个XML加载到内存,内存短时间内会增大,如果XML数据量大不推荐使用
        // 一次性加载整个XML文档
        GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:data options:kNilOptions error:nil];
        
        // SINGLE: 获取XML的根元素,拿到所有名称叫做video的子元素,该例子的XML根元素为数组
        NSArray *eleArray = [doc.rootElement elementsForName:@"video"];
        
        for (GDataXMLElement *ele in eleArray) {
            WXVideo *video = [[WXVideo alloc] init];
            
            // 逐个解析每个属性元素
            video.name = [ele attributeForName:@"name"].stringValue;
            video.image = [ele attributeForName:@"image"].stringValue;
            video.url = [ele attributeForName:@"url"].stringValue;
            video.ID = [ele attributeForName:@"id"].stringValue;
            video.length = [ele attributeForName:@"length"].stringValue;
            
            // 将解析好的模型添加到数据源数组
            [self.videos addObject:video];
        }
        
        // 刷新tableView数据
        [self.tableView reloadData];
        
    }];
}

你可能感兴趣的:(05.iOS JSON,XML数据解析)