iOS开发中数据结构解析详谈:XML和JSON
解析:按照约定好的格式去提取数据
后台开发人员按照约定好的格式去存入数据,前端开发人员以约定好的格式读取数据。
主要流行的数据格式有两种:XML/JSON
<1> XML相对于JSON,语法更接近于人的思想,规范,常用于大数据的解析;但是,逐行解析效率较低,传输占用带宽;
<2> JSON语法,更便于机器解读,解析效率高,传输快,但由于是整体解析方式,不能用于大数据的处理,占用内存。
A、XML:
一、XML:Extensible Markup language(可扩展标记语⾔言),主流数 据格式之⼀一,可以⽤用来存储和传输数据。
二、XML数据格式的功能:
1、数据交换
2、内存管理
3、用作配置文件
三、XML数据结构的语法:
1、声明
2、节点使用一对标签表示。起始和结束。
3、根节点是起始节点,只有一个。节点可以嵌套。
4、节点可以有值。存储在一对标签中。
1 <?xml version = "1.0" encoding= "UTF-8" ?> 2 3 <xmlFlie> 4 <student positon = "iOS屌丝"> 5 <name>lee</name> 6 <gender>男</gender> 7 <hobby>旅游</hobby> 8 <age>23</age> 9 </student> 10 11 12 <student positon = "iOS老鸟"> 13 <name>ha</name> 14 <gender>男</gender> 15 <hobby>跑步</hobby> 16 <age>24</age> 17 </student> 18 19 20 <student positon = "iOS菜鸟"> 21 <name>kris</name> 22 <gender>女</gender> 23 <hobby>读书</hobby> 24 <age>22</age> 25 </student> 26 27 28 <student positon = "iOS大牛"> 29 <name>mac</name> 30 <gender>男</gender> 31 <hobby>美元</hobby> 32 <age>31</age> 33 </student> 34 35 36 <student positon = "iOS小牛"> 37 <name>IPone</name> 38 <gender>男</gender> 39 <hobby>iOS</hobby> 40 <age>20</age> 41 </student> 42 43 44 <student positon = "iOS工程师"> 45 <name>攻城狮</name> 46 <gender>男</gender> 47 <hobby>加薪</hobby> 48 <age>24</age> 49 </student> 50 51 </xmlFlie>
XML:解析的两种工作原理
1)SAX解析:基于事件回调的解析机制。逐行解析,效率低,占用内存小。适合大数据解析。
使用类: 系统提供的NSXMLParser
2)DOM解析:把解析数据全部读入内存,初始化成树型结构,逐层进行解析,效率高,占用内存高。适合小数据的解析。
使用类:谷歌提供的第三方的GDataXMLNode
1)SAX解析:
1、NSXMLParser是iOS自带的解析类。采用SAX方式解析数据。
2、解析过程由NSXMLParser协议方法回调。
3、解析过程:开始标签 -> 取值 -> 结束标签 -> 取值
◀️代码演示:
1 #pragma mark -- SAX 解析数据 -- 2 3 - (IBAction)handleSAXParser:(id)sender { 4 5 // 解析之前 把数组元素清空 6 7 [self.dataSouce removeAllObjects]; 8 9 // self.dataSouce = nil; 10 11 12 // 1/ 获取本地文件 13 NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Student" ofType:@"xml"]; 14 15 16 17 // 2/创建解析工具对象 18 19 NSXMLParser *paser = [[NSXMLParser alloc]initWithData:[NSData dataWithContentsOfFile:filePath]]; 20 21 22 // 3/设置事件回调的delegate 23 24 paser.delegate = self; 25 26 27 28 // 4/开始解析 29 30 [paser parse]; 31 32 33 // 5/释放所有权 34 35 [paser release]; 36 37 38 39 } 40 41 #pragma mark -- NSMLParserDelegate -- 42 43 44 //开始读到开始标签时 45 46 -(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{ 47 48 49 // NSLog(@"%@",elementName); 50 51 if ([elementName isEqualToString:@"student"]) { 52 53 self.per = [[Person alloc]init]; 54 55 _per.positon = attributeDict[@"positon"]; 56 57 58 } 59 60 61 } 62 63 //当读到结束标签时 64 65 -(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{ 66 67 68 69 if ([elementName isEqualToString:@"name"]) { 70 71 self.per.name = self.str; 72 73 }else if ([elementName isEqualToString:@"gender"]){ 74 75 76 self.per.gender = self.str; 77 78 }else if ([elementName isEqualToString:@"age"]){ 79 80 self.per.age = self.str; 81 82 }else if ([elementName isEqualToString:@"hobby"]){ 83 84 85 self.per.hobby = self.str; 86 }else if ([elementName isEqualToString:@"student"]){ 87 88 89 [self.dataSouce addObject: self.per]; 90 91 [self.per release]; 92 // NSLog(@"%@",self.dataSouce); 93 94 // NSLog(@"......%ld",self.dataSouce.count); 95 96 } 97 98 99 } 100 101 102 //当解析结束时 103 104 - (void)parserDidEndDocument:(NSXMLParser *)parser{ 105 106 NSLog(@"***%@",self.dataSouce); 107 108 109 // 刷新界面,重新获取数据 110 [self.tableView reloadData]; 111 112 } 113 114 115 //当读到内容结束时 116 117 - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{ 118 119 self.str = string;//存储对应标签内容 120 121 // NSLog(@"%@",self.str); 122 123 } 124 125 126 #pragma mark -- 懒加载 -- 127 128 129 - (NSMutableArray *)dataSouce{ 130 if (!_dataSouce) { 131 self.dataSouce = [[NSMutableArray alloc]init]; 132 } 133 return [[_dataSouce retain]autorelease] ; 134 } 135 136 137 - (void)didReceiveMemoryWarning { 138 [super didReceiveMemoryWarning]; 139 // Dispose of any resources that can be recreated. 140 } 141 142 #pragma mark - Table view data source 143 144 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 145 #warning Potentially incomplete method implementation. 146 // Return the number of sections. 147 return 1; 148 } 149 150 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 151 #warning Incomplete method implementation. 152 // Return the number of rows in the section. 153 154 // NSLog(@"******%ld",self.dataSouce.count); 155 156 157 return self.dataSouce.count; 158 } 159 160 161 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 162 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"reuse" forIndexPath:indexPath]; 163 164 // Configure the cell... 165 166 Person *per = self.dataSouce[indexPath.row]; 167 168 cell.textLabel.text = per.name; 169 170 171 return cell; 172 }
2)DOM解析:
1.GDataXMLNode是Google提供的开源XML解析类,对libxml2.dylib进行了OC得封装。
2. GDataXMLNode 由谷歌提供开源的基于C语言的libxml2.dylib动态链接库(相当于libxml2.2.dylib的快捷方式),进行了封装而成的OC的XML数据解析类。解析效率较高。
(导入对应类库:)
1】. target - Build settings - Header Search Paths 添加:/usr/inculde/libxml2
2】. target - Bulid Phases - LinkBinary 添加: libxml2.dylib
(导入对应类库:)
1】. target - Build settings - Header Search Paths 添加:/usr/inculde/libxml2
2】. target - Bulid Phases - LinkBinary 添加: libxml2.dylib
◀️代码:
1 #pragma mark -- DOM Parser -- 2 3 4 - (IBAction)handleRootParser:(id)sender { 5 6 // 解析之前 把数组元素清空 7 8 [self.dataSource removeAllObjects]; 9 10 11 // 获取文件路径 12 13 NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Student" ofType:@"xml"]; 14 15 // 根据路径初始化字符串对象 16 17 NSString *str = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil]; 18 19 // 将解析的内容写入GDataXMLDocumnet 20 21 GDataXMLDocument *document = [[GDataXMLDocument alloc]initWithXMLString:str options:0 error:nil]; 22 23 // GDataXMLDocument 获取节点(获取根节点) 24 25 GDataXMLElement *rootElement = [document rootElement]; 26 27 // NSLog(@"%@",rootElement); 28 29 30 NSArray *stuElements = [rootElement elementsForName:@"student"]; 31 32 // NSLog(@"%@",stuElements); 33 34 // 对数组进行遍历 35 36 for (GDataXMLElement *element in stuElements) { 37 38 // 获取student节点下 name/gender/hobby/age 39 40 GDataXMLElement *nameElement = [[element elementsForName:@"name"] firstObject];//只有一个name节点 41 42 GDataXMLElement *genderElement = [[element elementsForName:@"gender"] firstObject]; 43 44 GDataXMLElement *hobbyElement = [[element elementsForName:@"hobby"] firstObject]; 45 46 47 GDataXMLElement *ageElment = [[element elementsForName:@"age"] firstObject]; 48 49 50 51 Person *per = [[Person alloc]init]; 52 53 // 获取节点中的内容 为per赋值 54 55 per.name = [nameElement stringValue]; 56 57 per.gender = [genderElement stringValue]; 58 59 per.hobby = [hobbyElement stringValue]; 60 61 per.age = [ageElment stringValue]; 62 63 64 // 65 66 GDataXMLNode *node = [element attributeForName:@"postion"]; 67 68 69 per.positon = [node stringValue]; 70 71 // NSLog(@"%@",per.age); 72 73 74 [self.dataSource addObject:per]; 75 76 [per release]; 77 78 } 79 80 // NSLog(@"-----------%@",self.dataSource); 81 82 // 重读数据,刷新界面 83 84 [self.tableView reloadData]; 85 86 } 87 88 -(NSMutableArray *)dataSource{ 89 90 if (!_dataSource) { 91 _dataSource = [[NSMutableArray alloc]init]; 92 } 93 return _dataSource; 94 } 95 96 97 #pragma mark ---DOM XParser --- 98 99 - (IBAction)handleXParser:(id)sender { 100 101 // 解析之前 把数组元素清空 102 103 [self.dataSource removeAllObjects]; 104 105 106 // 1/获取文件路径 107 108 NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Student" ofType:@"xml"]; 109 110 // 2、 根据路径转化成字符串对象 111 112 NSString *string = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil]; 113 114 115 // 3/解析内容存入 GDataXMLDocument 116 117 GDataXMLDocument *document = [[GDataXMLDocument alloc]initWithXMLString:string options:0 error:nil]; 118 119 120 // 4/获取所有标签为name的节点 121 122 NSArray *nameElements = [document nodesForXPath:@"//name" error:nil]; 123 124 125 // 5/获取所有gender hobby age 节点 126 127 NSArray *genderElements = [document nodesForXPath:@"//gender" error:nil]; 128 129 NSArray *hobbyElements = [document nodesForXPath:@"//hobby" error:nil]; 130 131 NSArray *ageElements = [document nodesForXPath:@"//age" error:nil]; 132 133 134 // 6/获取student节点 135 136 NSArray *sutdentElements = [document nodesForXPath:@"//student" error:nil]; 137 138 // NSLog(@"studentElements == %@",sutdentElements); 139 140 141 for (int i = 0; i < nameElements.count; i ++) { 142 143 GDataXMLElement *nameElement = nameElements[i]; 144 145 GDataXMLElement *genderElement = genderElements[i]; 146 147 GDataXMLElement *hobbyElement = hobbyElements[i]; 148 149 GDataXMLElement *ageElement = ageElements[i]; 150 151 Person *per = [[Person alloc]init]; 152 153 per.name = [nameElement stringValue]; 154 155 per.gender = [genderElement stringValue]; 156 157 per.age = [ageElement stringValue]; 158 159 per.hobby = [hobbyElement stringValue]; 160 161 [self.dataSource addObject:per]; 162 163 [per release]; 164 165 } 166 167 // NSLog(@"%ld",self.dataSource.count); 168 169 170 // 刷新界面 171 172 [self.tableView reloadData]; 173 174 } 175 176 - (void)didReceiveMemoryWarning { 177 [super didReceiveMemoryWarning]; 178 // Dispose of any resources that can be recreated. 179 } 180 181 #pragma mark - Table view data source 182 183 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 184 #warning Potentially incomplete method implementation. 185 // Return the number of sections. 186 return 1; 187 } 188 189 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 190 #warning Incomplete method implementation. 191 // Return the number of rows in the section. 192 193 // NSLog(@"%ld",self.dataSource.count); 194 195 return self.dataSource.count; 196 } 197 198 199 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 200 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"reuse" forIndexPath:indexPath]; 201 202 // Configure the cell.. 203 204 Person *per = self.dataSource[indexPath.row]; 205 206 cell.textLabel.text = per.name; 207 208 return cell; 209 }
B、JSON数据结构:
一、JSON概念:
Javascript Object Notation ,轻量级的数据交换格式,采用完全独立于语言的文本格式,被称为理想的数据交换语言。
二、JSON数据结构的语法:
1、JSON文档有两种结构:对象、数据
2、对象以“{”开始,以“}”结束,是“名称/值”(KV:键值对)。名称和值间用“:”隔开;
3、数组以“[”开始,以“]”结束,中间是数据,数据以“,”分隔;
4、JSON中的数据类型:字符串、数值、BOOL、对象、数组。
三、示例:

四、JSON数据结构功能;
1、数据交换
2、内容管理
3、配置文件
五、代码演示:
#pragma mark -- handle Parser --
//系统解析
- (IBAction)handleSystomJSONParser:(id)sender {
//
[self.dataSocurce removeAllObjects];
// 将json格式数据转化为OC对象
// 1/获取文件路径
NSString *filePath = [[NSBundle mainBundle ] pathForResource:@"Person" ofType:@"json"];
// 2/ 根据路径转化为NSData
NSData *data = [NSData dataWithContentsOfFile:filePath ];
// 3/解析:
NSArray *arr = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
// 4/
// NSLog(@"%@",arr);
for (int i = 0; i < arr.count; i ++) {
Person *per = [[Person alloc]init];
per.name = [arr[i] objectForKey:@"name"];
[self.dataSocurce addObject:per];
[per release];
}
[self.tableView reloadData];
}
//第三方解析
- (IBAction)handleThirdPartJSONParser:(id)sender {
// JSONKit 通过给NSString、NSData添加分类的方式,增加解析功能
// 1、获取文件路径
NSString *filePath = [[NSBundle mainBundle ] pathForResource:@"Person" ofType:@"json"];
#pragma mark --- 两种方法将json格式数据转化为OC对象 --
/*
// 2 *******第一种方式根据文件路径初始化为字符串对象 ***************
、
NSString *jsonString = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
// 3、解析为OC对象
NSArray *arr = [jsonString objectFromJSONString];
NSLog(@"%@",arr);*/
// 2. ****** 第二种方式 转化为NSData对象*************
[self.dataSocurce removeAllObjects];
NSData *jsonData = [NSData dataWithContentsOfFile:filePath];
// 3/解析:(可变与不可变)
NSArray *arr = [jsonData objectFromJSONData];
// NSLog(@"%@",arr);
for (id x in arr) {
Person *per = [[Person alloc]init];
per.name = [x objectForKey:@"name"];
[self.dataSocurce addObject:per];
[per release];
}
[self.tableView reloadData];
// NSMutableArray *arr = [jsonData mutableObjectFromJSONData];
#pragma mark ---- 第三方中提供的方法:-----
//// 1、将oc对象转换成JSON格式的数据
//
// NSArray *array = @[@"1",@"2",@"3"];
//// [array JSONData];//转化为JSON格式Data
//
//// [array JSONString];//转化为JSON格式字符串;
//
// NSString *str = @"123";
//
// [str JSONString];
//
//
//
// NSDictionary *dic = @{@"name":@"haha",@"age":@"18"};
//
// [dic JSONString];//转化为JSON格式字符串;
// [dic JSONData];//转化为JSON格式Data
}
-(NSMutableArray *)dataSocurce{
if (!_dataSocurce) {
self.dataSocurce = [NSMutableArray array];
}
return [[_dataSocurce retain]autorelease];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
#warning Potentially incomplete method implementation.
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
#warning Incomplete method implementation.
// Return the number of rows in the section.
return self.dataSocurce.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"reuseIdentifier" forIndexPath:indexPath];
// Configure the cell...
Person *per = self.dataSocurce[indexPath.row];
cell.textLabel.text = per.name;
return cell;
}
(辛苦手敲,转载请注明出处!)

浙公网安备 33010602011771号