您的位置:首页 > 理论基础 > 数据结构算法

UI day 14 XML JSON数据结构解析

2015-12-21 20:58 435 查看
                                       XML数据结构
1.解析:就是按照约定好(假象)的格式提取数据的过程解析
提供数据方(后台):工作就是把数据按照一定的格式存储起来
提取数据方(前台):工作就是把数据按照一定得格式读取出来
主流的格式:XML格式    JSON格式  此两种格式无论前台还是后台都必须熟悉

2.XML的数据以标签的形式存在,标签有开始标签和结束标签,管这一对标签叫做节点
没有父节点的节点叫做根节点,没有子节点的节点叫做叶子节点,而我们使用的数据都存在叶子节点中存储

3.XML解析的两种工作原理
(1)SAX  基于事件回调(找代理)的解析方式,逐行解析,效率低,适合大数据解析,是系统提供的
(2)DOM 把要解析的数据一下子全部读取到内存中,把数据初始化成树状结构,逐层进行解析,效率高,只适合小数据解析(谷歌提供的第三方解析方式)

                SAX解析      利用storyboard布局   在建一个Model类

(1)@interface
SAXViewController
()<NSXMLParserDelegate>
//存储从xml文件中解析出来的学生对象
@property
(nonatomic,retain)NSMutableArray
*dataSource;
@property
(nonatomic,retain)Student
*student;//使用学生对象存储读取到的信息
@property
(nonatomic,retain)NSMutableString
*string;//存储读取到节点中的数据
@end
@implementation
SAXViewController
(2)- (void)dealloc
{
   
self.dataSource
=
nil;
   
self.student
=
nil;
   
self.string
=
nil;
    [super
dealloc];
}
(3)懒加载
- (NSMutableArray
*)dataSource
{
   
if
(_dataSource
==
nil) {
       
self.dataSource
= [NSMutableArray
arrayWithArray:0];
    }
   
return
[[_dataSource
retain]autorelease];
}
(4) - (IBAction)handleParser:(UIBarButtonItem
*)sender {
//    NSLog(@"解析");
//   
系统提供的解析XML文件的类NSXMLParser
//    1.获取文件路径
   
NSString
*filePath = [[NSBundle
mainBundle]
pathForResource:@"Students.xml"
ofType:nil];
//    2.创建NSData对象
   
NSDatT a
*data = [NSData
dataWithContentsOfFile:filePath];
   
//3.创建解析对象
   
NSXMLParser
*parser = [[NSXMLParser
alloc]initWithData:data];
//    4.指定代理
    parser.delegate
=
self;
//    5.开始解析
    [parser
parse];
//    6.释放
    [parser release];
}

(5) #pragma mark XMLparser的代理方法
//开始解析的时候触发这个方法
- (void)parserDidStartDocument:(NSXMLParser
*)parser
{
//    NSLog(@"开始解析了");
//  
开始解析的时候清空数值中的内容
    [self.dataSource
removeAllObjects];
}
//读取到开始标签的时候触发
- (void)parser:(NSXMLParser
*)parser didStartElement:(NSString
*)elementName namespaceURI:(NSString
*)namespaceURI qualifiedName:(NSString
*)qName attributes:(NSDictionary
*)attributeDict
{
//    NSLog( @"%@",attributeDict);
//    NSLog(@"%@",elementName);
//   
当读取到student开始标签的时候创建学生对象
   
if
([elementName
isEqualToString:@"student"])
{
       
self.student
= [[Student
alloc]init];
       
       
self.student.position
= attributeDict[@"position"];
     
    }
//    #####21读取到开始标签就初始化字符串self.string
   
self.string
= [NSMutableString
stringWithCapacity:0];
}
//当读取到开始标签后的数据时触发
- (void)parser:(NSXMLParser
*)parser foundCharacters:(NSString
*)string//string就是存储的读取得到的数据
{
//    NSLog(@"%@",string);
   
//使用属性保存节点中间的数据
//    #####21由于系统的解析能力是有限的如果节点中的内容过长不能够一次性全部读取,此时,要把每次读取的内容拼接到一起
    [self.string
appendString:string];
}

//读取到结束标签的时候触发
- (void)parser:(NSXMLParser
*)parser didEndElement:(NSString
*)elementName namespaceURI:(NSString
*)namespaceURI qualifiedName:(NSString
*)qName
{
//     NSLog(@"==%@",elementName);
   
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)parserDidEndDocument:(NSXMLParser
*)parser
{
  
//    NSLog(@"%@",self.dataSource);
//     NSLog(@"解析结束了");
//   
在这里让tableView重新刷新一次UI,重新走一遍数据源代理方法
    [self.tableView
reloadData];
   
}

(6) - (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];
   
Student
*s =
self.dataSource[indexPath.row];//根据cell的下标取出对应的学生
    cell.textLabel.text
= s.name;
   
return
cell;
}
@end
                                DOM解析    利用storyboard布局

GDataXMLNode是有Google提供的开源的基于C语言的libxml2.dylib动态链接类库封装的OC解析类,效率比较高
 使用GDataxmlNade的步骤:
 1.target - Build Phases-link Binary
添加libxml2.dylib
 2.target - Build setting header search Pach 
添加
/usr/include/libxml2
 libxml2.dylib
和libxml2.2dylib的区别:前一个是快捷方式,永远指向最新的实体类库,而后一个才是真正的实体类库,使用前一个的好处,当系统的实体类库更新的时候,老版本的项目就无需再重新导入实体类库

(1)
@interfaceDOMViewController
()
@property
(nonatomic,retain)NSMutableArray
*dataSource;
@end
(2)
@implementation
DOMViewController
- (void)dealloc
{
   
self.dataSource
=
nil;
    [super
dealloc];
}

(3)懒加载
- (NSMutableArray
*)dataSource
{
   
if
(_dataSource
==nil)
{
       
self.dataSource
= [NSMutableArray
arrayWithCapacity:0];
    }
    return
[[_dataSource
retain]autorelease];
}

(4) - (IBAction)handleRootParser:(UIBarButtonItem
*)sender {
//   
解析开始之前把数组中的元素清空
    self.dataSource
=
nil;
   
//    1.读取文件的路径
   
NSString
*filePath = [[NSBundle
mainBundle]
pathForResource:@"Students.xml"
ofType:nil];
//    2.将文件内容存储到字符串中
   
NSString
*xmlStr = [NSString
stringWithContentsOfFile:filePath
encoding:NSUTF8StringEncoding
error:nil];
//    3.将要解析的内容写入到GDataxmlDocument内容
//    /
第二个参数是一个预留参数,就是这个方法的作者,在写着方法时预留一个参数的位置,留待以后对方的扩充
   
GDataXMLDocument
*document = [[GDataXMLDocument
alloc]initWithXMLString:xmlStr
options:0
error:nil];
//    GDataXMLElement节点类
//    GDataXMLNode
它里面存的是属性对象 
是个属性类
//   4.
获取document中所有的根节点
   
GDataXMLElement
*rootElement = [document
rootElement];
//    NSLog(@"%@",rootElement);
//   5.
获取根节点下的所有student节点
 NSArray 
*stuElements = [rootElement
elementsForName:@"student"];
//    NSLog(@"%@",stuElements);
//   6.
遍历数组,获取每一个student节点
   
for
(GDataXMLElement
*stuElement
in
stuElements) {
//   7.
获取student节点下的name/age/gnder/says节点
       
GDataXMLElement
*nameElement = [[stuElement 
elementsForName:@"name"]lastObject];
       
GDataXMLElement
*ageElement = [[stuElement
elementsForName:@"age"]lastObject];
       
GDataXMLElement
*genderElement = [[stuElement
elementsForName:@"gender"]lastObject];
       
GDataXMLElement
*saysElement = [[stuElement
elementsForName:@"says"]lastObject];
       
/*
//     
打印每个节点对象中的数据
stringvalue方法可以返回节点对象中的数据
        NSLog(@"%@",[nameElement stringValue]);
        NSLog(@"%@",[ageElement stringValue]);
        NSLog(@"%@",[genderElement stringValue]);
        NSLog(@"%@",[saysElement stringValue]);
        NSLog(@"==================================");
        */
//   8.创建学生对象,存储节点对象中的数据
       
Student
*stu = [[Student
alloc]init];
        stu.name
= [nameElement
stringValue];
        stu.age
= [ageElement
stringValue];
        stu.gender
= [genderElement
stringValue];
        stu.says
= [saysElement
stringValue];
//   10.
取出学生节点对象中的属性
       
GDataXMLNode
*node = [stuElement
attributeForName:@"position"];
        stu.position
= [node
stringValue];
//   9. 
将学生对象添加到数组中
        [self.dataSource
addObject:stu];

        [stu
release];
     
    }
    [self.tableView
reloadData];//更新UI
   
NSLog(@"%@",self.dataSource);
//   
释放掉xml文本对象
    [document
release];
}

(5) - (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];
   
Student
*s =
self.dataSource[indexPath.row];
    cell.textLabel.text
= s.position;
  
   
return
cell;
}
@end

                                             JSON数据结构解析
(1)
#import
"JSONViewController.h"
#import
"Student.h"
#import
"JSONKit.h"
@interface
JSONViewController
()
@property
(nonatomic,retain)NSMutableArray
*dataSource;
@end
(2) @implementation
JSONViewController
- (void)dealloc
{
   
self.dataSource
=
nil;
    [super
dealloc];
}
(3)懒加载
- (NSMutableArray
*)dataSource
{
   
if
(_dataSource
==
nil) {
       
self.dataSource
= [NSMutableArray
arrayWithCapacity:0];
    }
   
return
[[_dataSource
retain]autorelease];
}

(4) - (IBAction)handleSystem:(UIBarButtonItem
*)sender {
   
self.dataSource
=
nil;
   
NSLog(@"系统");
//    1.获取文件路径
   
NSString
*filePath = [[NSBundle
mainBundle]
pathForResource:@"Student.json"
ofType:nil];
//    2.将json文件读取到NSDate对象中
   
NSData
*data = [NSData
dataWithContentsOfFile:filePath];
//    NSJSONReadingMutableContainers返回的容器是可变的容器
//    NSJSONReadingMutableLeaves返回的找到的数据时可不的数据
//    3.json文件的最外层是数组,所有用数组接收
 
NSMutableArray  *dataSource = [NSJSONSerialization
JSONObjectWithData:data
options:NSJSONReadingMutableContainers
error:nil];
   
//    NSLog(@"%@",dataSource);
//   3.
数组中都是字典对象,所以遍历字典
   
for
(NSDictionary
*dic
in
dataSource) {
       
Student
*stu = [[Student
alloc]init];
        [stu
setValuesForKeysWithDictionary:dic];
        [self.dataSource
addObject:stu];
        [stu
release];
   
    }
   
//   
刷新UI
    [self.tableView
reloadData];

}

(5) - (IBAction)handleThird:(UIBarButtonItem
*)sender {
   
self.dataSource
=
nil;
//    NSLog(@"第三方");
//    1.获取文件路径
   
NSString
*filePath = [[NSBundle
mainBundle]
pathForResource:@"Student.json"
ofType:nil];

{
   
NSString
*jsonStr = [NSString
stringWithContentsOfFile:filePath
encoding:NSUTF8StringEncoding
error:nil];
// 2. 第一种解析 
通过JSON格式字符串解析JSON数据
objectFromJSONString返回的数据可以使用可变容器接收也可以使用不可变容器接收
  
NSArray
*dataArray =[jsonStr
objectFromJSONString];
//    NSLog(@"%@",dataArray);
 }
  
//  2. 第二种解析
通过NSData对象完成解析
   
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];
   
}

(6) - (NSInteger)numberOfSectionsInTableView:(UITableView
*)tableView {
   
return
1;
}
- (NSInteger)tableView:(UITableView
*)tableView numberOfRowsInSection:(NSInteger)section
{
   
return
self.dataSource.count<
bcf2
span style="font-size:24px;">;
}

- (UITableViewCell
*)tableView:(UITableView
*)tableView cellForRowAtIndexPath:(NSIndexPath
*)indexPath {
   
UITableViewCell
*cell = [tableView
dequeueReusableCellWithIdentifier:@"json"
forIndexPath:indexPath];
   
   
Student
*stu =
self.dataSource[indexPath.row];
   
    cell.textLabel.text
= stu.age;

   
return
cell;
}
@end
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  xml json UI 可视化编程