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:解析的两种工作原理
 
 1SAX解析:基于事件回调的解析机制。逐行解析,效率低,占用内存小。适合大数据解析。
 
使用类: 系统提供的NSXMLParser
 
 2DOM解析:把解析数据全部读入内存,初始化成树型结构,逐层进行解析,效率高,占用内存高。适合小数据的解析。
 
 使用类:谷歌提供的第三方的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的快捷方式),进行了封装而成的OCXML数据解析类。解析效率较高。
 
 (导入对应类库:)
 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;
 }

 

 
(辛苦手敲,转载请注明出处!)
 
 
 
 
 
 
 
 
posted @ 2015-09-22 21:02  抠得儿  阅读(303)  评论(0)    收藏  举报