iOS数据解析UI_14
提供数据方(后台):工作就是把数据按照一定的格式存储起来
提取数据方(前台):工作就是把数据按照一定的格式读取出来
主流的格式:XML格式 / JSON格式 ,此两种格式无论前台还是后台都必须熟悉
XML以标签的形式存在,标签由开始标签和结束标签,这一对标签就做节点;
没有父节点的节点叫做根节点,没有子节点的节点就做叶子节点,而我们要使用的数据都在叶子节点中存储;
XML解析的两种工作原理:
Student.h
@interface Student : NSObject
@property(nonatomic,copy)NSString *name;//姓名
@property(nonatomic,copy)NSString *gender;//性别
@property(nonatomic,copy)NSString *age;//年龄
@property(nonatomic,copy)NSString *says;//座右铭
@property(nonatomic,retain)NSString *position;//属性
@end
Student.m
@implementation Student
-(void)dealloc{
self.name = nil;
self.gender = nil;
self.says = nil;
self.age = nil;
self.position = nil;
[super dealloc];
}
//防止未找到key值所对的value造成Crash
- (void)setValue:(id)value forUndefinedKey:(NSString *)key{
}
@end
—————————————————
两个方法的cell显示一样UITableViewCell
SAXViewController.m
#import "SAXViewController.h"
#import "Student.h"
@interface SAXViewController ()<NSXMLParserDelegate>
//存储从xml中解析出来的学生对象
@property(nonatomic,retain)NSMutableArray *dataSource;
@property(nonatomic,retain)Student *student;//存储使用学生对象读取到的信息
@property(nonatomic,retain)NSMutableString *string;//存储读取到节点中的数据
@end
@implementation SAXViewController
- (void)dealloc{
self.dataSource = nil;
self.student = nil;
self.string = nil;
[super dealloc];
}
- (IBAction)handleParser:(UIBarButtonItem *)sender {
//NSXMLParser 系统提供的解析xml文件的类
//第一步:获取文件路径
NSString *filePath = [[NSBundle mainBundle]pathForResource:@"Students.xml" ofType:nil];
//第二步:创建解析对象
//创建一个NSData对象
NSData *data = [NSData dataWithContentsOfFile:filePath];
NSXMLParser *parser =[[NSXMLParser alloc]initWithData:data];
//制定代理
parser.delegate = self;
//开始解析
[parser parse];
//释放
[parser release];
}
- (NSMutableArray *)dataSource{
if (_dataSource == nil) {
self.dataSource = [NSMutableArray arrayWithCapacity:0];
}
return [[_dataSource retain]autorelease];
}
#pragma mark xmlPoarserDelegate 代理方法
//开始解析的时候触发这个方法
- (void)parserDidStartDocument:(NSXMLParser *)parser{
// NSLog(@"开始解析了");
//开始解析的时候清空数组中的内容
[self.dataSource removeAllObjects];
}
//读到开始标签的时候开始触发
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
//当读取到Student开始标签的时候创建学生对象
if ([elementName isEqualToString:@"Student"]) {
self.student = [[Student alloc]init];
self.student.position = attributeDict[@"position"];
}
//读取到开始标签就初始化字符串self.string
self.string = [NSMutableString stringWithCapacity:0];
}
//读到结束标签的时候开始触发
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
if ([elementName isEqualToString:@"name"]) {
self.student.name = self.string;
}else if([elementName isEqualToString:@"age"]){
self.student.age = self.string;
}else if([elementName isEqualToString:@"gender"]){
self.student.gender = self.string;
}else if ([elementName isEqualToString:@"says"]){
self.student.says = self.string;
}else if ([elementName isEqualToString:@"Student"]){
//把学生对象添加到数组中
[self.dataSource addObject:self.student];
[self.student release];
}
}
//当读到开始标签后的数据触发
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
//string 存储的就是读到的数据
//由于系统的解析能力是有限的,如果节点中的内容过长,不能一次性全部读取,此时要把,每次读取到的内容拼接在一起
[self.string appendString:string];
}
//结束解析的时候触发
- (void)parserDidEndDocument:(NSXMLParser *)parser{
// NSLog(@"解析结束了");
//在这里让tableView重新刷新一下ui,重新走一遍数据源方法
[self.tableView reloadData];
}
//返回分区个数
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
//返回行数
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.dataSource.count;
}
//显示
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"sax" forIndexPath:indexPath];
//根据cell的下标取出对应的学生
Student *s = self.dataSource[indexPath.row];
cell.textLabel.text = s.name;
return cell;
}
最终效果:
——————————————————————————————————————————————————
————————————————第二部分Dom解析———————————————
两个方法的cell显示一样UITableViewCell
2. GDataXMLNode 是由Google提供的开源的基于C语言的libxml2.dylib动态链接类库封装的OC xml解析类,效率比较高
使用GDataXMLNode 步骤:
1.target -->Build Phases--link Binary 添加libxml2.dylib
2.target -->Build setting 搜 header seach Path 双击后缀添加 /usr/include/libxml2
libxml2.dylib 和 libxml2.2dylib 的区别:前一个是快捷方式,永远指向最新的实体类库,而后一个才是真正的实体类库,使用前一个好处,当系统实体类库更新的时候,老版本的项目就无需再重新导入实体类库;
DOMViewController.m
#import "DOMViewController.h"
#import "GDataXMLNode.h"
#import "Student.h"
@interface DOMViewController ()
@property(nonatomic,retain)NSMutableArray *dataSource;
@end
@implementation DOMViewController
- (void)dealloc{
self.dataSource = nil;
[super dealloc];
}
//懒加载创建数组
- (NSMutableArray *)dataSource{
if (_dataSource == nil) {
self.dataSource = [NSMutableArray arrayWithCapacity:0];
}
return [[_dataSource retain]autorelease];
}
==============RootParser解析=================
- (IBAction)handleRootParser:(UIBarButtonItem *)sender {
//解析开始之前把数组中的元素清空
self.dataSource = nil;
//拿到文件的路径
NSString *filePath = [[NSBundle mainBundle]pathForResource:@"Students.xml" ofType:nil];
//将文件内容存储到字符串中
NSString *xmlStr = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
//将要解析的内容写入到GDataXMLDocument 类中
//第二个参数是一个预留参数,就是这个方法的作者,在写这个方法时预留一个参数的位置,留待以后对方的扩充
GDataXMLDocument *document = [[GDataXMLDocument alloc]initWithXMLString:xmlStr options:0 error:nil];
// GDataXMLElement 节点类
// GDataXMLNode 属性类
//获取document 中所有的根节点
GDataXMLElement *rootElement = [document rootElement];
// NSLog(@"%@",rootElement);//验证
//获取根节点下的所有Student节点
NSArray *stuElements = [rootElement elementsForName:@"Student"];
// NSLog(@"%@",stuElement);//验证
//遍历数组,获取每一个Student节点
for (GDataXMLElement *stuElement in stuElements) {
//获取Student节点下的name/age/gender/says 因为只有一个元素所有firstObject和lastObject一样
GDataXMLElement *nameElement = [[stuElement elementsForName:@"name"]lastObject];
GDataXMLElement *ageElement = [[stuElement elementsForName:@"age"]lastObject];
GDataXMLElement *genderElement = [[stuElement elementsForName:@"gender"]firstObject];
GDataXMLElement *saysElement = [[stuElement elementsForName:@"says"]firstObject];
/*//打印每个节点对象中的数据 验证!
NSLog(@"%@",[nameElement stringValue]);
NSLog(@"%@",[ageElement stringValue]);
NSLog(@"%@",[genderElement stringValue]);
NSLog(@"%@",[saysElement stringValue]);
NSLog(@"________________________");
*/
//创建学生对象,存储节点对象中的数据
Student *stu = [[Student alloc]init];
stu.name = [nameElement stringValue];
stu.age = [ageElement stringValue];
stu.gender = [genderElement stringValue];
stu.says = [saysElement stringValue];
//取出学生节点对象中的属性
GDataXMLNode *node = [stuElement attributeForName:@"position"];
stu.position = [node stringValue];
//将学生对象添加到数组织中
[self.dataSource addObject:stu];
[stu release];
}
[self.tableView reloadData];
// NSLog(@"%@",self.dataSource); //验证
//释放xml文本对象
[document release];
}
RootParser解析效果:
————————————————————————————————————————————
==============xPath相对路径解析=================
- (IBAction)handleXPath:(UIBarButtonItem *)sender {
//清空数组
[self.dataSource removeAllObjects];
//拿到文件的路径
NSString *filePath = [[NSBundle mainBundle]pathForResource:@"Students.xml" ofType:nil];
//将文件内容存储到字符串中
NSString *xmlStr = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
//将要解析的内容写入到GDataXMLDocument 类中
//第二个参数是一个预留参数,就是这个方法的作者,在写这个方法时预留一个参数的位置,留待以后对方的扩充
GDataXMLDocument *document = [[GDataXMLDocument alloc]initWithXMLString:xmlStr options:0 error:nil];
//通过相对路径获取name,age,gender,says 节点
//姓名节点
NSArray *nameElements = [document nodesForXPath:@"//name" error:nil];
//年龄节点
NSArray *ageElements = [document nodesForXPath:@"//age" error:nil];
//性别节点
NSArray *genderElements = [document nodesForXPath:@"//gender" error:nil];
//座右铭节点
NSArray *saysElements = [document nodesForXPath:@"//says" error:nil];
//学生节点
NSArray *studentElements = [document nodesForXPath:@"//Student" error:nil];
//求出学生节点数组中元素的个数
int count = (int)studentElements.count;
for (int i = 0; i < count; i ++) {
//创建节点对象接收数组中对应位置的元素
GDataXMLElement *nameElement = nameElements[i];
//取出年龄节点
GDataXMLElement *ageElement = ageElements[i];
//取出性别节点
GDataXMLElement *genderElement = genderElements[i];
//取出says节点
GDataXMLElement *saysElement = saysElements[i];
//取出学生节点
GDataXMLElement *studentElement = studentElements[i];
//创建学生对象存储节点中的内容
Student *s = [[Student alloc]init];
s.name = [nameElement stringValue];
s.age = [ageElement stringValue];
s.gender = [genderElement stringValue];
s.says = [saysElement stringValue];
//取出学生节点中的属性
GDataXMLNode *node = [studentElement attributeForName:@"position"];
s.position = [node stringValue];
//添加到数组中
[self.dataSource addObject:s];
//释放
[s release];
}
//刷新UI界面
[self.tableView reloadData];
[document release];
}
//返回分区
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.dataSource.count;
}
//显示
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"dom" forIndexPath:indexPath];
//取值给model类Student对象
Student *s = self.dataSource[indexPath.row];
//赋值
cell.textLabel.text = s.position;
return cell;
}
xPath相对路径解析效果:
——————————————————————————————————————————————
=======================第三部分JiSON=========================
两个方法的cell显示一样UITableViewCell
JSONViewController.m
#import "JSONViewController.h"
#import "Student.h"
#import "JSONKit.h"
@interface JSONViewController ()
@property(nonatomic,retain)NSMutableArray *dataSource;
@end
@implementation JSONViewController
- (void)dealloc{
self.dataSource = nil;
[super dealloc];
}
//懒加载
- (NSMutableArray *)dataSource{
if (_dataSource == nil) {
self.dataSource = [NSMutableArray arrayWithCapacity:0];
}
return [[_dataSource retain]autorelease];
}
==============系统方法解析=================
- (IBAction)handleSystomParser:(UIBarButtonItem *)sender {
//清空字典内容
self.dataSource = nil;
//1.获取文件路径
NSString *filePath = [[NSBundle mainBundle]pathForResource:@"Student.json" ofType:nil];
//2.将JSON文件读取到Data对象中
NSData *date = [NSData dataWithContentsOfFile:filePath];
// NSJSONReadingMutableContainers = (1UL << 0), 返回容器是可变容器
// NSJSONReadingMutableLeaves = (1UL << 1), 返回的找到的数据的是可变的数据
//json的最外层是数组,所以用数组接收
NSMutableArray *dataSource = [NSJSONSerialization JSONObjectWithData:date options:(NSJSONReadingMutableContainers) error:nil];
//数组中都是字典,所以遍历字典
for (NSDictionary *dic in dataSource) {
//创建一个学生对象
Student *stu = [[Student alloc]init];
//kvc赋值
[stu setValuesForKeysWithDictionary:dic];
//加到数组里
[self.dataSource addObject:stu];
//释放
[stu release];
}
//刷新ui
[self.tableView reloadData];
}
系统方法解析效果:
——————————————————————————————————
==============第三方解析=================
- (IBAction)handleThridParer:(UIBarButtonItem *)sender {
//清除数组
self.dataSource = nil;
//获取文件路径
NSString *filePath = [[NSBundle mainBundle]pathForResource:@"Student.json" ofType:nil];
/*系统方法暂时不用(注掉)
NSString *jsonStr = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
//1.通过json格式的字符串解析json数据 objectFromJSONString返回的数据可以使用可变容器接收也可以使用不可变容器接收
NSArray *dataArray = [jsonStr objectFromJSONString];
NSLog(@"%@",dataArray);
*/
新方法
//2.通过NSDate对象完成解析 objectFromJSONData返回的数据可以使用可变容器接收也可以使用不可变容器接收
NSData *data = [NSData dataWithContentsOfFile:filePath];
NSArray *dataArray2 = [data objectFromJSONData];
// NSLog(@"%@",dataArray2); 验证!
//数组中都是字典,所以遍历字典
for (NSDictionary *dic in dataArray2) {
//创建
Student *stu = [[Student alloc]init];
[stu setValuesForKeysWithDictionary:dic];
[self.dataSource addObject:stu];
[stu release];
}
[self.tableView reloadData];
}
//返回分区
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
//返回行数
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.dataSource.count;
}
//显示
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"json" forIndexPath:indexPath];
//取值
Student *s = self.dataSource[indexPath.row];
//显示
cell.textLabel.text = s.says;
return cell;
}
第三方解析效果:
iOS数据解析UI_14的更多相关文章
- IOS数据解析JSON
//非原创 作为一种轻量级的数据交换格式,json正在逐步取代xml,成为网络数据的通用格式. 有的json代码格式比较混乱,可以使用此“http://www.bejson.com/”网站来进行JSO ...
- 【原】iOS学习38网络之数据解析
1. 解析的基本的概念 解析:从事先规定好的格式中提取数据 解析前提:提前约定好格式,数据提供方按照格式提供数据.数据获取方则按照格式获取数据 iOS开发常见的解析:XML解析.JOSN解析 2. X ...
- iOS - JSON 数据解析
iOS - JSON 数据解析 前言 NS_CLASS_AVAILABLE(10_7, 5_0) @interface NSJSONSerialization : NSObject @availab ...
- iOS开发笔记3:XML/JSON数据解析
这篇主要总结在iOS开发中XML/JSON数据解析过程用到的方法.XML数据解析主要使用SAX方式的NSXMLParser以及DOM方式的GDataXML,JSON数据解析主要使用NSJSONSeri ...
- iOS学习—JSON数据解析
关于在iOS平台上进行JSON解析,已经有很多第三方的开源项目,比如TouchJson,JSONKit,SBJon等,自从iOS5.0以后,苹果SDK推出了自带的JSON解决方案NSJSONSer ...
- iOS - Plist 数据解析
前言 NS_AVAILABLE(10_6, 4_0) @interface NSPropertyListSerialization : NSObject 如果对象是 NSArray 或 NSDicti ...
- iOS - XML 数据解析
前言 @interface NSXMLParser : NSObject public class NSXMLParser : NSObject 1.XML 数据 XML(Extensible Mar ...
- iOS GET、POST数据解析
在实际开发中,JSON数据解析更简单易行,一般均使用json数据解析,因此,程序猿们请务必和后台搞好关系,让他给你json数据. XML解析: ios SDK提供了NSXMLParser和lib ...
- 浅议iOS网络数据解析
/*------------------------------------ 数据解析: 1.JSON数据 --------------------------------*/ 重点:1.什么是JSO ...
随机推荐
- Kinect2.0 MultiSourceFrameReader 的 AcquireLatestFrame 方法获取不到帧的解决方案
先把大致要写的东西写一下,手里的活忙完了再完善. 在代码中使用下边的语句,获取Kinect中,colorFrame, depthFrame, bodyIndex三种帧,但是经常会遇到在后边的程序中处理 ...
- FJUT第三周寒假作业《第九集,离间计》栈
第九集,离间计 TimeLimit:1000MS MemoryLimit:128MB 64-bit integer IO format:%I64d Problem Description 拥有了 ...
- Android查缺补漏(线程篇)-- IntentService的源码浅析
本文作者:CodingBlock 文章链接:http://www.cnblogs.com/codingblock/p/8975114.html 在Android中有两个比较容易弄混的概念,Servic ...
- 实验与作业(Python)-04 数据类型、数学函数与字符串
截止日期 实验目标 继续熟悉for循环与turtle 数值运算符 math库常用函数 字符串转化为数值类型(int, float, complex) 字符串常用函数 实验内容 任务1.使用for代替w ...
- 炫酷:一句代码实现标题栏、导航栏滑动隐藏。ByeBurger库的使用和实现
本文已授权微信公众号:鸿洋(hongyangAndroid)原创首发. 其实上周五的时候已经发过一篇文章.基本实现了底部导航栏隐藏的效果.但是使用起来可能不是很实用.因为之前我实现的方式是继承了系统的 ...
- java中static特殊性和final(static成员直接被访问,this不能用在static方法中,static不可访问非static)
java的static关键字 java中,static修饰的成员变量和成员方法叫静态变量和静态方法,不依赖类特定的实例,被类的所有实例共享. 静态变量或类变量 和 实例变量,区别是: 静态变量在内存中 ...
- Linux系统中查询发行版本号以及内核版本的命令总结
了解Linux发行版本的版本号是一项非常重要的事情,大多数软件对系统的版本都有要求,发行版本号与软件不匹配,软件将无法安装或者无法使用.这边集合市面上流行的Linux发行版本版本号查询方法.有了这边文 ...
- Android Studio精彩案例(二)《仿微信动态点击底部tab切换Fragment》
转载本专栏文章,请注明出处,尊重原创 .文章博客地址:道龙的博客 现在很多的App要么顶部带有tab,要么就底部带有tab.用户通过点击tab从而切换不同的页面(大部分情况时去切换fragment). ...
- [CSDN_Markdown] 使用CSDN Markdown编辑器
简介 最近CSDN支持Markdown语法写博客了,甚是欢喜.前几天写了一篇实验了下,感觉不错.准备写几篇文章介绍一下如何使用CSDN的Markdown编辑器写博客,不求全面,但求够用,望大家批评指正 ...
- activiti 动态配置 activiti 监听引擎启动和初始化(高级源码篇)
1.1.1. 前言 用户故事:现在有这样一个需求,第一个需求:公司的开发环境,测试环境以及线上环境,我们使用的数据库是不一样的,我们必须能够任意的切换数据库进行测试和发布,对数据库连接字符串我们需要加 ...