/**
* 解析:按规定的格式提取数据的过程. 后台人员按照约定好的格式存入数据,前端开发人员按照约定好的格式读取数据.
*/
//主流的两大数据格式:XML JSON
/**XML解析两种工作原理:
SAX解析:基于事件回调机制.逐行读取进行解析.效率低.适合大数据解析.使用系统提供的类NSXMLParser
DOM解析:把解析数据读入内存,初始化为树形结构.逐层解析,效率较高,适合小数据解析.使用谷歌提供的第三方GDataXMLNode.
*/
XML :
SAX:
@interface SAXViewController ()<NSXMLParserDelegate>
@property(nonatomic,strong)NSMutableArray *dataSource;
//存储节点名称
@property(nonatomic,copy)NSString *elementName;
@end
@implementation SAXViewController
- (IBAction)handleParse:(id)sender {
//获取本地文件
NSString *file = [[NSBundle mainBundle]pathForResource:@"Students" ofType:@"xml"];
//使用系统提供的NSXMLParser类解析(SAX)
//1.创建一个解析工具对象
NSData *data = [NSData dataWithContentsOfFile:file];
NSXMLParser *parser = [[NSXMLParser alloc]initWithData:data];
//2.设置代理
parser.delegate = self;
//3.开始解析
[parser parse];
}
#pragma mark - NSXMLParserDelegate
//开始解析时
- (void)parserDidStartDocument:(NSXMLParser *)parser{
//创建数组
self.dataSource = [NSMutableArray array];
}
//开始读取起始标签
/**
* @param parser 解析工具对象
* @param elementName 标签的名称
* @param namespaceURI 命名空间
* @param qName 限定名称(通常和命名空间结合使用)
* @param attributeDict 标签的属性字典
*/
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString*)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict{
NSLog(@"起始标签:%@",elementName);
//获取开始标签名称
self.elementName = elementName;
//当起始标签名为Student时 创建学生对象
if ([elementName isEqualToString:@"Student"]) {
//创建Student对象
Student *stu = [[Student alloc]init];
//存储到数据源数组中
[self.dataSource addObject:stu];
}
}
//获取开始标签和结束标签之间的值
//string 就是标签的值.
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
NSLog(@"%@",string);
//取出model
Student *stu = [self.dataSource lastObject];
//赋值给stu;
[stu setValue:string forKey:self.elementName];
}
//开始读取结束标签
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString*)namespaceURI qualifiedName:(NSString *)qName{
NSLog(@"结束标签:%@",elementName);
//防止重新给elementName赋值;
self.elementName = nil;
}
//结束读取
-(void)parserDidEndDocument:(NSXMLParser *)parser{
NSLog(@"%@",self.dataSource);
}
-(void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError{
NSLog(@"ERROR:%@",parseError);
}
DOM:
/**
* DOM解析:会将内容全部读入内存,把数据读成一个树形结构,按树形结构的层级读取内容.
GDataXMLNode:实在C语言的libxml2动态链接库基础上封装的OC的XML解析类.解析效率相对SAX高(快将近10倍)
使用 GDataXMLNode步骤:
1. target ->Build Phase ->LinkBinary添加libxml2.tbd
2.target -> Build Setting --HeaderSearch Path添加 /usr/include/libxml2;
*/
//DOM解析
- (IBAction)handleDom:(id)sender {
self.dataSource = [NSMutableArray array];
//获取xml文件路径
NSString *file = [[NSBundle mainBundle]pathForResource:@"Students" ofType:@"xml"];
//1.将解析内容写入GDataXMLDocument文档中
NSString *xmlStr = [NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil];
GDataXMLDocument *docment = [[GDataXMLDocument alloc]initWithXMLString:xmlStr options:0 error:nil];
//2.获取节点
//获取根节点
GDataXMLElement *rootElement = [docment rootElement];
//获取GDataXMLDocument对象中的根节点,再根据根节点获取下面的所有子节点
NSArray *childEles =rootElement.children;
//遍历子节点数组
for (GDataXMLElement *childElement in childEles) {
// NSLog(@"%@",childElement);
//创建学生对象
Student *stu = [[Student alloc]init];
//遍历当前节点的所有子节点.
//subElement.name:获取节点名称
//subElement.stringValue:获取节点对应的值.
for (GDataXMLElement *subElement in childElement.children) {
[stu setValue:subElement.stringValue forKey:subElement.name];
}
//存储到数据源
[_dataSource addObject:stu];
}
NSLog(@"%@",_dataSource);
}
JSON:
//使用系统提供的类
- (IBAction)handleSystem:(id)sender {
self.dataSource = nil;
//获取json文件路径
NSString *file = [[NSBundle mainBundle]pathForResource:@"Model" ofType:@"geojson"];
//根据文件路径初始化NSData对象
NSData *data = [NSData dataWithContentsOfFile:file];
//系统类的解析
/**
返回值的类型取决于json数据最外层的类型
* @param NSJSONReadingOptions
NSJSONReadingMutableContainers :如果最外层的容器类型(字典或数组),该选项可以获取可变的类型
NSJSONReadingMutableLeaves:如果json中数据中子节点的值是字符串,就把该字符串转为可变的.
NSJSONReadingAllowFragments:不可变的(通常使用).
*
*/
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragmentserror:nil];
NSLog(@"%@",dic);
//处理数据
NSArray *arr = dic[@"data"];
for (NSDictionary *dic in arr) {
Activity *model = [[Activity alloc]init];
//KVC赋值
[model setValuesForKeysWithDictionary:dic];
//存储到数组中
[self.dataSource addObject:model];
}
[self.tableView reloadData];
}
- (IBAction)handleOther:(id)sender {
//使用第三方类:(看附件:最后一个元素不要加",").导入:
#import "JSONKit.h"
//JSONKit 通过给NSString,NSData添加分类形式,增加解析功能
//获取文件路径
NSString *file = [[NSBundle mainBundle]pathForResource:@"Model" ofType:@"geojson"];
// NSString *dataStr = [NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil];
// NSDictionary *dic = [dataStr objectFromJSONString];
// NSLog(@"ssss%@",dic);
//根据文件路径初始化得到NSData
NSData *data = [NSData dataWithContentsOfFile:file];
//解析(可变)
NSMutableDictionary *dics = [data mutableObjectFromJSONData];
/**
* OC对象和JSON数据之间转换:将字符串,数组,字典转为JSON数据.
*/
NSString *str = @"tssssss";
NSString *str2 = @"taaaaa";
NSArray *arr2 = @[str,str2];
NSString *strJson = [arr2 JSONString];
NSLog(@"%@",strJson);
NSArray *arr = dics[@"data"];
for (NSDictionary *dic in arr) {
Activity *model = [[Activity alloc]init];
//KVC赋值
[model setValuesForKeysWithDictionary:dic];
//存储到数组中
[self.dataSource addObject:model];
}
[self.tableView reloadData];
}