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 - <NSXMLParserDelegate>
// SINGLE: 当开始解析XML文档的时候调用,只调用一次
- (void)parserDidStartDocument:(NSXMLParser *)parser;

// SINGLE: 开始解析某个元素的时候调用,如果有多个元素,会调用多次,调用一次解析一个元素
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)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 - <NSXMLParserDelegate>
// SINGLE: 当开始解析XML文档的时候调用,只调用一次
- (void)parserDidStartDocument:(NSXMLParser *)parser
{
    NSLog(@"parserDidStartDocument");
}

// SINGLE: 开始解析某个元素的时候调用,如果有多个元素,会调用多次,调用一次解析一个元素
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)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
01.GDataXML编译错误解决方案.png

  • 设置GDataXML的编译环境为非ARC环境
02.GDataXML的编译环境为非ARC环境.png

  • 设置Other Linker Flags,添加一项 -lxml2
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];
        
    }];
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容