IOS--UI--LessonParse 数据解析 XML JSON
来源:互联网 发布:魔神英雄传 知乎 编辑:程序博客网 时间:2024/06/09 21:57
一 什么是解析?
1.解析:按照约定好的格式提取数据 就是解析
2.数据的提供方:后台开发人员 按照约定好的格式存入数据
数据的提取方:按照约定好的格式提出数据
3.目前主流格式:XML/JSON
① XML 以标签的形式 管理数据 使用比较长的一种方式 比较复杂 逐渐被代替中
/*
1.标签包括:开始标签 结束标签,一对开始和结束标签叫节点;
2.没有父节点的节点叫做根节点,没有子节点的节点叫做叶子节点;我们要取的数据一般都在叶子节点里
3.解析的两种形式:
3.1 SAX 解析 (适合解析大数据 大数据喜欢吃内存 ) NSXMLParser
基于事件回调的形式解析,自己不想做 让别人做就是回调 找代理 ,逐行解析 系统提供的就是这样的
优点:对内存占有率较低
缺点:效率低 适合大数据
3.2 DOM 解析
解析时,会把数据解析到内存中,把读入的数据初始化成树状结构,然后一层一层的读取,适用于小数据 谷歌提供的 GDataXMLNode
*/
②JSON 即 JavaScript Object Natation,它是一种轻量级的数据交换格式,非常适合于服务器与客户端的交互 ,逐渐代替 XML
二 XML
1. 首先看一下 xml 的 数据源
<?xml version = "1.0" encoding = "UTF-8"?><lanou27>// 开始标签 <Student position = "团一波"> //开始标签 <name>Nyx</name> <gender>Girl</gender> <age>18</age> <say>我们来吧</say> </Student>//结束标签 <Student position = "等我大招">//开始标签 <name>Sona</name> <gender>Girl</gender> <age>18</age> <say>我不会说话啊</say> </Student>//结束标签 <Student position = "看我一挑五">//开始标签 <name>瑞萌萌</name> <gender>Girl</gender> <age>19</age> <say>断剑重铸之日,骑士归来之时</say> </Student>//结束标签 <Student position = "我的小熊呢!">//开始标签 <name> Anne</name> <gender>Girl</gender> <age>15</age> <say>看见我的小熊了么</say> </Student>//结束标签</lanou27>//结束标签
注:带有斜杠的代码 我们定义为结束标签,反之不带则是开始标签
2.解析过程
①SAX(SimpleAPI for XML)
(适合解析大数据 大数据喜欢吃内存 ) NSXMLParser
基于事件回调的形式解析,自己不想做 让别人做就是回调 找代理 ,逐行解析 系统提供的就是这样的
只能读,不能修改,只能顺序访问,适合解析大型XML,解析速度快,实现异构系统的数据访问,实现跨平台
从文档的开始通过每一节点移动,定位一个特定的节点
优点:对内存占有率较低
缺点:效率低 适合大数据
②XML解析步骤:
1、实例化NSXMLParser,传入从服务器接收的XML数据,我们刚在上面定义的 XML 就可以在代码中使用
2、定义解析器代理
常用的代理方法:
1. 开始解析XML文档- (void)parserDidStartDocument:(NSXMLParser *)parser;2. 开始解析某个元素,会遍历整个XML,识别元素节点名称,如<Student>开头- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict;3. 文本节点,得到文本节点里存储的信息数据。 节点中的数据<name>NYX</name> 这里不可以赋值- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string;4. 结束某个节点 如</Student>开头- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName注意:在解析过程中,2、3、4三个方法会不停的重复执行,直到遍历完成为止5.解析XML文档结束- (void)parserDidEndDocument:
3、解析器解析,通过解析代理方法完成XML数据的解析。
下面是代码;
#import "SAXTableViewController.h"#import "StudentMode.h"@interface SAXTableViewController ()<NSXMLParserDelegate>//设置代理需要遵守的协议@property (nonatomic,retain)NSMutableArray *dataSoutse;@property(nonatomic,retain)StudentMode *stu;@property (nonatomic,copy)NSString *string;@end@implementation SAXTableViewController//我们用的 MRC 所以要手动释放- (void)dealloc{ [_dataSoutse release]; [_string release]; [_stu release]; [super dealloc];}//程序运行会走的方法- (void)viewDidLoad { [super viewDidLoad]; // 注册 cell 完成我们想要实现的 button 功能 [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"reuseIdentifier"]; [self configureNavigationBar];}// 注:网上请求的数据不可以懒加载#pragma mark -----懒加载-----lazy-loading-(NSMutableArray *)dataSoutse{ if (!_dataSoutse) { self.dataSoutse =[NSMutableArray arrayWithCapacity:1]; }return [[_dataSoutse retain]autorelease];}//添加 button 属性 完成点击事件-(void)configureNavigationBar{ UIBarButtonItem *rightItem =[[UIBarButtonItem alloc]initWithTitle:@"解析" style:(UIBarButtonItemStylePlain) target:self action:@selector(HandlePrase:)]; self.navigationItem.rightBarButtonItem =rightItem; [rightItem release];}// 我们的点击事件 通过点击 button 完成将需要的值传入界面中-(void)HandlePrase:(UIBarButtonItem *)sender{ //使用系统提供的 NSXMLParser 解析,解析原理:// 1.读取文件路径 NSString *filePath =[[NSBundle mainBundle]pathForResource:@"Students" ofType:@"xml"];// 2.读取数据 NSData *data =[NSData dataWithContentsOfFile:filePath];// 3.创建解析对象 NSXMLParser *parser =[[NSXMLParser alloc]initWithData:data];// 4.设置代理 parser.delegate =self;// 5.开始解析 [parser parse]; [parser release];}#pragma mark----解析代理方法的实现------//开始解析文档会触发的方法- (void)parserDidStartDocument:(NSXMLParser *)parser{// 下拉刷新之前需要将上次的东西清空 这样当你刷新的时候就不会重复出现同样的内存 不停的扩充你的indexPath.row; self.dataSoutse =nil;}//结束解析文档会触发的方法- (void)parserDidEndDocument:(NSXMLParser *)parser{// 重新加载数据 刷新作用 [self.tableView reloadData];}//当读取到开始标签的时候触发 比如:<Student> 不带/的- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{ NSLog(@"%@",elementName); //设定的 position 里的值是以键值对的形态存在 存放在attributeDict if ([elementName isEqualToString:@"Student"]) { self.stu =[[StudentMode alloc]init]; //存储开始节点的属性值 self.stu.position =attributeDict[@"position"]; } }//当读取到标签内容后触发的方法, 比如:Nyx 不能在这里赋值- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{ self.string =string;}//读取到结束标签的时候会触发的方法 ,比如:</Student>- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{ // 这就是赋值的过程 if ([elementName isEqualToString:@"name"]) { self.stu.name =self.string; }else if ([elementName isEqualToString:@"age"]){ self.stu.age =self.string; }else if ([elementName isEqualToString:@"gender"]){ self.stu.gender =self.string; }else if ([elementName isEqualToString:@"say"]){ self.stu.say =self.string; }else if ([elementName isEqualToString:@"Student"]){ [self.dataSoutse addObject:self.stu]; } }
总结:
SAX解析XML,是基于事件通知的模式,一边读取XML文档一边处理,不必等整个文档加载完之后才采取操作,当在读取解析过程中遇到需要处理的对象,会发出通知对其进行处理。
2.DOM 解析模型就像一个树结构,根节点 ,叶子节点;
GDataXMLNode 是Google 提供的开源的类库,底层有 c 语言实现, < libxml.2.dylib > (动态链接库),C 语言把这个动态链接类库封装成了 OC 中的 XML 解析类,效率比较高;
① GDataXMLNode 使用步骤:
1 taget–Build phases–> link Binary–> 添加一个 libxml2.dylib;
2 taget–>BuildSetting –>Header seacher –>添加了”/usr/include/libxml2”;
libxml2.dylib 相当于一个快捷方式 ,永远都是指向的是 最新的类库, libxml2.2才是真实的类库,当系统类库更新的适合,老版本的 libxml2.dylib 就不需要导入更新后的类库
② DOM 分两种:一种是绝对路径解析 就是只有一条路到达终点;一种是相对路径解析 有多中方法可以达到目的
①布局
#import "DOMTableViewController.h"#import "StudentMode.h"#import "GDataXMLNode.h"@interface DOMTableViewController ()@property (nonatomic,retain)StudentMode *stu;@property (nonatomic,retain)NSMutableArray *dataSource;@end@implementation DOMTableViewController- (void)dealloc{ [_dataSource release]; [_stu release]; [super dealloc];}- (void)viewDidLoad { [super viewDidLoad]; //注册 cell [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"cell"]; [self configuerRight]; [self configuerLeft ];}#pragma mark ------lazyLoading------//重写 setter 方法 懒加载-(NSMutableArray *)dataSource{ if (!_dataSource) { self.dataSource =[NSMutableArray arrayWithCapacity:1]; }return [[_dataSource retain] autorelease];}//根节点 绝对路径-(void)configuerLeft{ UIBarButtonItem *leftItem =[[UIBarButtonItem alloc]initWithTitle:@"RootParser" style:(UIBarButtonItemStylePlain) target:self action:@selector(HandleRootParser:)]; self.navigationItem.leftBarButtonItem =leftItem; [leftItem release];}// 相对路径 XPath-(void)configuerRight{ UIBarButtonItem *rightItem =[[UIBarButtonItem alloc]initWithTitle:@"XPath" style:(UIBarButtonItemStylePlain) target:self action:@selector(HandleXPath:)]; self.navigationItem.rightBarButtonItem =rightItem; [rightItem release];}
根节点解析
//通过根节点进行解析-(void)HandleRootParser:(UIBarButtonItem *)sender{#warning 清空之前的数据 self.dataSource = nil;// [self.dataSource removeAllObjects]; 也可以达到效果 // 1.获取文件路径 NSString *filePath =[[NSBundle mainBundle]pathForResource:@"Students" ofType:@"xml"]; // 2.根据文件路径初始化 字符串对象 NSString *xmlStr =[NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil]; //3.将解析内容写入 GDataXMLDocment 这个文档 等于存入了内容; GDataXMLDocument *docment =[[GDataXMLDocument alloc]initWithXMLString:xmlStr options:0 error:nil]; //GDataXMLElement (节点对象) // 4.获取文档中的节点对象 -->GDataXMLElement;获取根节点 // 不仅会打印根节点 根节点包括的东西也会打印出来 GDataXMLElement *rootElement =[docment rootElement]; // NSLog(@"%@",rootElement); // 5.获取根节点下的所有的 Student 节点 NSArray *studentArr=[rootElement elementsForName:@"Student"]; // 6.对数组遍历获取每个学生的节点信息 for (GDataXMLElement *element in studentArr) { // 7.获取 Student 下的叶子节点 就是他的属性// name 节点 GDataXMLElement *nameElement =[[element elementsForName:@"name"] firstObject];// age GDataXMLElement *ageElement =[[element elementsForName:@"age"] firstObject];// gender GDataXMLElement *genderElement =[[element elementsForName:@"gender"] firstObject];// say GDataXMLElement *sayElement =[[element elementsForName:@"say"] firstObject];// 8 创建学生对象 对其赋值 StudentMode *stu =[[StudentMode alloc]init]; stu.name =[nameElement stringValue]; stu.age =[ageElement stringValue]; stu.gender =[genderElement stringValue]; stu.say =[sayElement stringValue];//9 获取节点中属性值,属性即 GDataXMLNode GDataXMLNode *node =[element attributeForName:@"position"]; stu.position =[node stringValue];// 10将赋值结束的学生对象 添加到数组 中 [self.dataSource addObject:stu]; [stu release]; }#warning 解析完之后要刷新 [self.tableView reloadData];}
注: 解析完的刷新和 之前的数组清空很重要,反之会出现一样的东西不停的重复
XPath 相对路径解析
#pragma mark------相对路径解析-----(void)HandleXPath:(UIBarButtonItem *)sender{ self.dataSource =nil; // 1.获取文件路径 NSString *filePath =[[NSBundle mainBundle]pathForResource:@"Students" ofType:@"xml"]; // 2.根据文件路径初始化 字符串对象 NSString *xmlStr =[NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil]; //3.将解析内容写入 GDataXMLDocment 这个文档 等于存入了内容; GDataXMLDocument *docment =[[GDataXMLDocument alloc]initWithXMLString:xmlStr options:0 error:nil]; //4. 获取所有的 name 节点 这里是相对路径 只要能找到这个那么就好#warning 一个/ 是绝对路径 两个// 是相对路径 NSArray *nameElements= [docment nodesForXPath:@"//name" error:nil]; NSArray *ageElements =[docment nodesForXPath:@"//age" error:nil]; NSArray *genderElements =[docment nodesForXPath:@"//gender" error:nil]; NSArray *sayElements =[docment nodesForXPath:@"//say" error:nil];// 根节点 NSArray *stuElements =[docment nodesForXPath:@"//Student" error:nil]; int count = (int )nameElements.count;//强制转换// 5.遍历获取学生信息 for (int i =0; i <count; i++) { GDataXMLElement *nameElement = nameElements[i]; GDataXMLElement *ageElement =ageElements[i]; GDataXMLElement *genderElement =genderElements[i]; GDataXMLElement *sayElement =sayElements[i]; GDataXMLElement *stuElement =stuElements[i];// 6.取出节点中的值 为 stu 赋值 StudentMode *stu =[[StudentMode alloc]init]; stu.name = [nameElement stringValue]; stu.age =[ageElement stringValue]; stu.gender =[genderElement stringValue]; stu.say =[sayElement stringValue]; //获取节点中属性值,属性 GDataXMLNode GDataXMLNode *node=[stuElement attributeForName:@"position"];// 为属性赋值 stu.position =[node stringValue];// 6 添加到数组中 [self.dataSource addObject:stu]; [stu release]; } [self.tableView reloadData];}
总结:
1.根节点和 XPath 都是通过遍历 赋值 来找到你想要的数据
2.别忘了 在设定 section 和 row 的方法中开辟空间
3.重用 cell 方法
三 JSON 非常便利的解析方法 他的数据源和 XML 也不一样
[ { "name":"Nyx", "gender":"Girl", "age":15, "say":"你是看不起我么" }, { "name":"暴风女神", "gender":"Girl", "age":"17", "say":"风之化身听你差遣" }, { "name":"堕落天使 莫甘娜", "gender":"Gilr", "age":"18", "say":"他们将会痛苦不堪" }, { "name":"狂野女猎手 奶大力", "gender":"Girl", "age":"17", "say":"狂野 将使他们感到畏惧" }, { "name":"迅捷斥候 提莫", "gender":" Boy", "age":"16", "say":"我去前面探探路" } ]
最外层是数组 里面每一组数据是字典
2.解析代码
①系统解析
#import "JSONTableViewController.h"#import "StudentMode.h"#import "JSONKit.h"@interface JSONTableViewController ()@property (nonatomic,retain)NSMutableArray *dataSource;@end@implementation JSONTableViewController- (void)dealloc{ [_dataSource release]; [super dealloc];}//懒加载 重写 setter 方法-(NSMutableArray *)dataSource{ if (!_dataSource) { self.dataSource = [NSMutableArray arrayWithCapacity:0]; }return [[_dataSource retain] autorelease];}- (void)viewDidLoad { [super viewDidLoad]; [self configuerRight]; [self configuerLeft ]; [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"cell"]; // self.navigationItem.rightBarButtonItem = self.editButtonItem;}#pragma mark------系统的解析-(void)configuerLeft{ UIBarButtonItem *leftItem =[[UIBarButtonItem alloc]initWithTitle:@"系统" style:(UIBarButtonItemStylePlain) target:self action:@selector(HandleSystem:)]; self.navigationItem.leftBarButtonItem =leftItem; [leftItem release];}-(void)HandleSystem:(UIBarButtonItem *)sender{ self.dataSource = nil;// 1.获取文件路径 NSString *filePath =[[NSBundle mainBundle]pathForResource:@"Student"ofType:@"json"];// 2.根据文件路径 初始化 NSData 对象 NSData *data= [NSData dataWithContentsOfFile:filePath];// 3.解析了 NSMutableArray *arr =[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil]; self.dataSource =[NSMutableArray arrayWithCapacity:1]; for (NSDictionary *dic in arr) { StudentMode *stu =[[StudentMode alloc]init]; [stu setValuesForKeysWithDictionary:dic]; [self.dataSource addObject:stu]; [stu release]; } [self.tableView reloadData];}
② 第三方解析 需要引入你的第三方 我在这里用的是 JSONKit
#pragma mark-----第三方解析---------(void)configuerRight{ UIBarButtonItem *rightItem =[[UIBarButtonItem alloc]initWithTitle:@"第三方" style:(UIBarButtonItemStylePlain) target:self action:@selector(HandThirdPrase:)]; self.navigationItem.rightBarButtonItem =rightItem; [rightItem release];}-(void)HandThirdPrase:(UIBarButtonItem *)sender{ self.dataSource = nil; //JSONKit通过对NSString,NSData添加分类的形式,添加解析的功能 //JSONKit 通过对NSString ,NSData添加分类的形式,添加了一个解析的功能 //1,获取文件路径 NSString *filePath = [[NSBundle mainBundle ]pathForResource:@"Student" ofType:@"json"]; //2,根据文件路径初始化字符串对象 NSString *dataStr = [NSString stringWithContentsOfFile:filePath encoding:(NSUTF8StringEncoding) error:nil]; //3,解析OC对象,(返回值可以选择可变或不可变) //dataStr 调用分类的方法 NSArray *arr1 = [dataStr objectFromJSONString];// NSLog(@"%@",arr1); NSMutableArray *arr2 = [dataStr mutableObjectFromJSONString];// NSLog(@"%@",arr2); //根据文件路径初始化NSData 对象 NSData *data = [NSData dataWithContentsOfFile:filePath];// NSLog(@"%@",data);// 解析 (可变/不可变) 取不到数据???? NSArray *arr3 = [data objectFromJSONData];// NSLog(@"%@",arr3); NSMutableArray *arr4 = [data mutableObjectFromJSONData];// NSLog(@"%@",arr4); self.dataSource =[NSMutableArray arrayWithCapacity:1]; for (NSDictionary *dic in arr4) { StudentMode *stu =[[StudentMode alloc]init]; [stu setValuesForKeysWithDictionary:dic]; [self.dataSource addObject:stu]; [stu release]; } [self.tableView reloadData]; }
总结:
1.所有的解析数据 步骤大致:
①获取文件地址
②根据文件初始化你所订的对象类型
③存入数据
④遍历
⑤赋值
2. 方法的清空和刷新 是每一个解析方法必备!
3. XML 的方法 需要多练习掌握
- IOS--UI--LessonParse 数据解析 XML JSON
- iOS 数据解析 JSON XML
- UI进阶:数据解析(XML解析和JSON解析)
- IOS 请求数据解析 XML 和 JSON
- 【iOS】Plist-XML-JSON数据解析
- iOS 数据解析 JSON 和 XML
- 【iOS】Plist-XML-JSON数据解析
- iOS的Plist-XML-JSON数据解析
- iOS之数据解析 (JSON 、XML)
- ios 数据解析(XML,JSON)
- UI---JSON数据解析
- IOS--UI--XML 解析
- UI XML,JSON 数据结构解析
- 【iOS开发-95】JSON反序列化、XML数据解析以及主线程中的UI更新等小细节
- 23>IOS数据解析---------之JSON和XML解析
- ios开发系列之XML解析和JSON解析数据
- [ios]xml, json解析
- IOS-XML&JSON解析
- mybatis异常
- Android自定义弹窗效果
- MySQL 用户权限详细汇总
- oc003-set和get方法
- Palindrome Linked List
- IOS--UI--LessonParse 数据解析 XML JSON
- STL--关于权重问题的解决
- EventBus使用详解
- Socket编程《三》
- 【POJ】【3624】
- [leetcode] Trapping Rain Water
- Redis命令小细节
- oc004---oc的继承
- 贝叶斯决策