UIday1502:XML 、JSON 数据结构解析

来源:互联网 发布:帝国cms整站模板 编辑:程序博客网 时间:2024/05/16 18:06

XML 、JSON 数据结构解析

一、解析的概念
 所谓“解析”:从事先规定好的格式中提取数据
 解析的前提:提前约定好格式、数据提供⽅按照格式提供数据、数据获取⽅则按照格式获取数据
 iOS 开发常⻅的解析:XML解析、JSON解析等
 
 二、XML 数据结构
 XML:Extensible Markup language(可扩展标记语⾔),主流数据格式之⼀,可以⽤来存储和传输数据。
    数据交换
    内容管理
    用作配置文件
 XML数据结构的语法:
 声明
 节点使⽤一对标签表示。起始和结束标签。
 根节点是起始节点,只有⼀个。节点可以嵌套。
 节点可以有值。存储在⼀对儿标签中
 
 三、进行XML解析时使⽤到的SAX工具
 SAX解析 SAX:Simple API for XML。基于事件驱动的解析⽅式,逐⾏解析数据。(采⽤协议回调机制)
 NSXMLParser
 是iOS自带的 XML解析类。采⽤SAX方式解析数据。解析过程由 NSXMLParserDelegate 协议⽅法回调
 解析过程:开始标签 -> 取值 -> 结束标签 -> 取值

 四、DOM 解析:
 DOM:Document Object Model(⽂档对象模型)。解析时需要将XML文件整体读⼊,并且将XML结构化成树状,使用时再通过树状结构读取相关数据
 GDataXMLNode是Google提供的开源XML解析类,对libxml2.dylib进⾏了Objective-C的封装
 采⽤DOM方式解析数据iOS中包含⼀个C语⾔的动态链接库libxml2.dylib,解析速度⽐NSXMLParser快
 
 五、JSON 数据结构的概念
 Javascript Object Notation,轻量级的数据交换格式,采⽤完全独⽴于语言的⽂本格式,被称为理想的数据交换语⾔
 JSON
 ⽂文档有两种结构:对象、数据
 对象:以“{ ” 开始,以 “ } ” 结束,是 “名称/值”对⼉的集合。名称和值中间⽤“:”隔开。多个“名称/值”对之间⽤“,”隔开。类似OC中的字典。
 数组:以“[ ”开始,以“]”结束,中间是数据。数据以“,”分隔。JSON中的数据类型:字符串、数值、BOOL、对象、数组。
 JSON 数据结构的功能
    数据交换
    内容管理
    配置文件
 
 六、使⽤ Foundation 进⾏ JSON 解析
    NSJSONSerialization 对象的作⽤
 
 七、使用 JSONKit 进⾏ JSON 解析
 JSONDecoder 对象的作用
 NSString(JSONKitDeserializing) 类目的作⽤
 NSData(JSONKitDeserializing) 类⺫的作用
 NSString(JSONKitSerializing) 类⺫的作用
 NSArray(JSONKitSerializing) 类⺫的作用
 NSDictionary(JSONKitSerializing) 类⺫的作用
 
 总结
 数据解析:从某种格式的数据中提取⾃己所需要的数据。
 主流的数据交换格式有两种:XML和JSON
 XML 解析分为两种:SAX解析和DOM解析
 XML 解析⼯具:NSXMLParser、 GDataXMLNode、TochXML和KissXML等
 JSON 解析⼯工具:JSONKit、NSJSONSerialization、TouchJSON和SBJSON等,其中 NSJSONSerialization是系统提供的解析类,其解析效率是最⾼的



1 (在 Build Settings 搜索:Header Search Paths,把“/usr/include/libxml2”添加到相应的位置)
2 (在 Build Settings 搜索:“Other Linker Flags”,把“-lxml2”添加到相应的位置)
3 (在 Build Phases 页签 Compile Sources(5 items)--GDataXMLNode.m 后面双击 添加"-fno-objc-arc" )


ViewController.m

//需要先拖入三个文件:GDATA JSON SBJson。#import "ViewController.h"#import "Message.h"#import "GDataXMLNode.h"#import "JSONKit.h"#import "SBJson.h"@interface ViewController ()<NSXMLParserDelegate>@property(nonatomic,strong)NSMutableArray * dataArray;//用来拼接字符串@property(nonatomic,strong)NSMutableString * appendString;@end@implementation ViewController- (void)viewDidLoad {    [super viewDidLoad];    // Do any additional setup after loading the view, typically from a nib.}//逐行进行解析- (IBAction)xmlSax:(id)sender {    //xml 是一种可扩展标记语言    //由标签组成    //标签成对出现    //标签名自定        //SAX解析:逐行解析xml文件内容    //NSXMLParser        //准备数据//    [[NSBundle mainBundle] pathForResource:@"message.txt" ofType:nil];    NSString * filePath = [[NSBundle mainBundle] pathForResource:@"message" ofType:@"txt"];        NSLog(@"filePath = %@",filePath);//打印出来的是沙河路径        //URL    NSURL * fileUrl = [[NSURL alloc]initWithString:filePath];        //data 这个最后会转换成二进制 以后学习的很多东西都用这种方式    NSData * fileData = [NSData dataWithContentsOfFile:filePath];                //创建解析器    NSXMLParser * parser = [[NSXMLParser alloc]initWithData:fileData];        //设置代理    parser.delegate = self;        //启动解析    [parser parse];    }////需要GData工具文件(推荐使用这种)- (IBAction)xmlDom:(id)sender {        //准备路径    NSString * filePath = [[NSBundle mainBundle]pathForResource:@"message.txt" ofType:nil];    //转出data类型    NSData * data = [NSData dataWithContentsOfFile:filePath];    //创建GDataXML解析文档    GDataXMLDocument * xmlDoc = [[GDataXMLDocument alloc]initWithData:data options:0 error:nil];    //获取根节点    GDataXMLElement * rootElement = xmlDoc.rootElement;        //初始化数组    self.dataArray = [NSMutableArray array];        //便利查找    //GDataXMLElement 是结点类型    //children是一个数组,里面的每个元素都是结点类型    for (GDataXMLElement * m1 in rootElement.children) {                //创建model对象        Message * message = [[Message alloc]init];                //遍历m1中的子节点        for (GDataXMLElement * m2 in m1.children) {            //kvc            //stringValue就是结点之间的字符串            //name就是标签名            [message setValue:m2.stringValue forKey:m2.name];        }                //将model对象存入数组        [self.dataArray addObject:message];    }        //打印验证    for (Message *m in self.dataArray) {        NSLog(@"xmlDom = %@,%@,%@,%@",m.sender,m.receiver,m.content,m.date);    }        }//系统解析(推荐使用这种或者SBJson方法)- (IBAction)jsonSystem:(id)sender {        //准备路径    NSString * filePath = [[NSBundle mainBundle]pathForResource:@"message2.txt" ofType:nil];    //转出data类型    NSData * data = [NSData dataWithContentsOfFile:filePath];        //json解析    //错误 如果发现错误,用指针指向这个创建错误 的地址,方便查找原因    NSError * error = nil;    //JSON解析重点:    NSArray * tempArray = [NSJSONSerialization JSONObjectWithData:data options:(NSJSONReadingAllowFragments) error:&error];        NSLog(@"%@",tempArray);        //初始化数组    self.dataArray = [NSMutableArray array];    for (NSDictionary * dict in tempArray) {        //创建model对象        Message *m = [[Message alloc]init];                //给model对象赋值        //kvc        [m setValuesForKeysWithDictionary:dict];                //将model对象装入数组        [self.dataArray addObject:m];    }        //打印验证    for (Message *m in self.dataArray) {        NSLog(@"jsonSystem = %@,%@,%@,%@",m.sender,m.receiver,m.content,m.date);    }    }//JsonKit- (IBAction)jsonKit:(id)sender {        //准备路径    NSString * filePath = [[NSBundle mainBundle]pathForResource:@"message2.txt" ofType:nil];    //转出data类型    NSData * data = [NSData dataWithContentsOfFile:filePath];    //解析    NSArray * tempArray = [data objectFromJSONData];        NSLog(@"%@",tempArray);        //转成model对象    //初始化数组    self.dataArray = [NSMutableArray array];    for (NSDictionary * dict in tempArray) {        //创建model对象        Message *m = [[Message alloc]init];                //给model对象赋值        //kvc        [m setValuesForKeysWithDictionary:dict];                //将model对象装入数组        [self.dataArray addObject:m];    }        //打印验证    for (Message *m in self.dataArray) {        NSLog(@"jsonKit = %@,%@,%@,%@",m.sender,m.receiver,m.content,m.date);    }        }//SBJson- (IBAction)sbJson:(id)sender {        //准备路径    NSString * filePath = [[NSBundle mainBundle]pathForResource:@"message2.txt" ofType:nil];        //从路径的文件中读取字符串    NSString * s = [[NSString alloc]initWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];//    NSLog(@"s = %@",s);        SBJsonParser * jsonParser = [[SBJsonParser alloc]init];        NSArray * jsonArray = [jsonParser objectWithString:s];        NSLog(@"jsonArray = %@",jsonArray);        //转成model对象    //初始化数组    self.dataArray = [NSMutableArray array];    for (NSDictionary * dict in jsonArray) {        //创建model对象        Message *m = [[Message alloc]init];                //给model对象赋值        //kvc        [m setValuesForKeysWithDictionary:dict];                //将model对象装入数组        [self.dataArray addObject:m];    }        //打印验证    for (Message *m in self.dataArray) {        NSLog(@"sbJson = %@,%@,%@,%@",m.sender,m.receiver,m.content,m.date);    }    }- (void)didReceiveMemoryWarning {    [super didReceiveMemoryWarning];    // Dispose of any resources that can be recreated.}#pragma mark XMLParser 代理方法//1 开始解析文档-(void)parserDidStartDocument:(NSXMLParser *)parser{    NSLog(@"开始解析文档");    //准备工作 (eg: 初始化数组)    self.dataArray = [NSMutableArray array];    }//2 开始解析标签-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{    NSLog(@"开始解析标签");        if ([elementName isEqualToString:@"message"]) {                //创建model对象        Message * m = [[Message alloc]init];                //存入数组        [self.dataArray addObject:m];            }        //初始化空间拼接字符串    self.appendString  = [NSMutableString string];        }//3 获取文档-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{    NSLog(@"获取文档");    //该方法未必是一次性取出整个字符串,有可能会分成n段取出    //拼接字符串    NSLog(@"string = %@",string);        [self.appendString appendString:string];        NSLog(@"appendString = %@",_appendString);    }//4 结束标签解析-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{    NSLog(@"结束标签解析");        // 先找到model对象 (取最后一个对象)    Message * m = [self.dataArray lastObject];        // kvc    [m setValue:_appendString forKey:elementName];                // 使用完字符串 置空    self.appendString = nil;}//5 结束解析文档-(void)parserDidEndDocument:(NSXMLParser *)parser{    NSLog(@"结束解析文档");    for (Message *m in _dataArray) {        NSLog(@"sender: %@",m.sender);        NSLog(@"receiver: %@",m.receiver);        NSLog(@"content: %@",m.content);        NSLog(@"date: %@",m.date);    }}//6 解析文档发生错误-(void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError{    NSLog(@"解析文档发生错误");}@end

Message.h

#import <Foundation/Foundation.h>@interface Message : NSObject//属性名和标签名一定要一样//因为要使用kvc@property(nonatomic,copy)NSString * sender;@property(nonatomic,copy)NSString * receiver;@property(nonatomic,copy)NSString * content;@property(nonatomic,copy)NSString * date;@end

Message.m

#import "Message.h"@implementation Message-(void)setValue:(id)value forUndefinedKey:(NSString *)key{    //当查找没有相应的key值会自动选择执行这个方法,否则程序运行崩溃}@end

message.txt

<?xml version = "1.0" encoding = "UTF-8"?><messages><message><sender>张三</sender><receiver>李四</receiver><content>今晚如家402,不见不散</content><date>2015年9月14日</date></message><message><sender>王铁柱</sender><receiver>田二妞</receiver><content>今晚如家402,不见不散</content><date>2015年9月14日</date></message></messages>

message2.txt

[    {   "sender" : "张三",   "receiver"  : "李四",   "content" : "今晚如家402,不见不散",   "date" : "2014年9月14日"    },{"sender" : "王铁柱",   "receiver"  : "田二妞",   "content" : "今晚如家403,等你哦",   "date" : "2014年9月14日" }]



0 0
原创粉丝点击