今天讲到数据结构解析的内容:XML和JSON两种
XML数据结构:是扩展于HTML,主要使用标签对<start></start>
其解析有两种:
1.SAX解析(Simple API for XML)。是基于事件驱动的解析方式,逐行解析数据(采用协议回调机制)
NSXMLParser是iOS自带的XML解析类。解析过程由NSXMLParserDelegate协议方式回调
解析过程:开始标签-->取值-->结束标签-->取值
使用过程如下:
@interface TableViewController ()<NSXMLParserDelegate>
@property (nonatomic,retain) NSMutableArray *datasource;
@property (nonatomic,retain) NSString *startTag;//通过属性暂存起始标签
@end
NSXMLParser *aParser = [[NSXMLParser alloc] initWithData:[NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Students" ofType:@"xml"]]]; //1.创建对象
aParser.delegate = self; //2.指定代理对象
[aParser parse]; //3.开始解析
[aParser release]; //4.释放所有权
其中主要实现的协议方法有以下五种
- (void)parserDidStartDocument:(NSXMLParser *)parser;//解析器开始解析XML文本,通知代理对象解析器解析的起始时间点
- (void)parserDidEndDocument:(NSXMLParser *)parser;//解析器完成解析时,通知代理对象解析的结束时间点
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict;//当解析器得到起始标签时会调用该协议方法传递数值给代理对象
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName;//当解析器得到结束标签时会调用该协议方法传递数值给代理对象
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string;//当解析器得到节点的起始标签和结束标签之间的数据时会调用该协议方法传数据给代理对象
2.DOM解析(文档对象模型):谷歌的GDataXMLNode(是一个第三方类的使用)
解析时需要将xml文件整体读入,并且将XML结构化树状,使用时在通过树种结构读取相关数据
//获取整个文档
GDataXMLDocument *aDocument = [[GDataXMLDocument alloc] initWithXMLString:[NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Students" ofType:@"xml"] encoding:NSUTF8StringEncoding error:nil] options:0 error:nil];
GDataXMLElement *rootElement = [aDocument rootElement]; //获取根节点对象
NSArray *subElements = [rootElement elementsForName:@"student"];//获取子节点数组
//通过快速枚举获取每一个子节点对象
for (GDataXMLElement *anElement in subElements) {
Student *aStudent = [[Student alloc] init];(Student是自定义模型类)
NSString *name = [[[anElement elementsForName:@"name"] firstObject] stringValue];
aStudent.name = name;
NSLog(@"%@",[[anElement elementsForName:@"gender"] firstObject]);
NSString *gender = [[[anElement elementsForName:@"gender"] firstObject] stringValue];
aStudent.gender = gender;
int age = [[[[anElement elementsForName:@"age"] firstObject]stringValue] intValue];
aStudent.age = age;
[self.datasource addObject:aStudent];//将获取的每一个Student对象存放在datasource
[aStudent release];
}
JSON数据结构:轻量级的数据交换格式
JSON⽂文档有两种结构:对象、数据
对象:以“{”开始,以“}”结束,是“名称/值”对⼉儿的集合。名称和值中 间⽤用“:”隔开。多个“名称/值”对之间⽤用“,”隔开。类似OC中的字典。
数组:以“[”开始,以“]”结束,中间是数据。数据以“,”分隔。
JSON中的数据类型:字符串、数值、BOOL、对象、数组。
//使用系统自带的JSOM序列化类进行JSON解析
NSData *jsonData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Students" ofType:@"json"]];
NSMutableArray *elements = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:nil];
for (NSDictionary *dict in elements)
{
Student *aStudent = [[Student alloc] init];
aStudent.name = dict[@"name"];
aStudent.age = [dict[@"age"] intValue];
aStudent.gender = dict[@"gender"];
[self.datasource addObject:aStudent];
[aStudent release];
}
以上,JSON使用最频繁,结构简单,所占空间最少,序列化解析方法简洁方;而XML文档所占空间是json文件两倍还多,其两种解析方法中:SAX解析是逐行解析,当.xml文件中存在错误时也可以将之前的解析完成,,但是采用协议回调的方法,太过于复杂;而DOM没有使用协议回调的方法,但是将整篇文档读入后解析,一旦文档编辑出错,将无法解析,但是可以定位文档出错的位置
文章中提到的第三方类的使用:
获取地址:http://github.com
将获取到的类拖到工程中,会出现头文件导入错误的信息
// libxml includes require that the target Header Search Paths contain
// /usr/include/libxml2
// and Other Linker Flags contain
// -lxml2
#import <libxml/tree.h>//导入错误
处理方法:
点击‘+’
添加该文件后。在Bulid settings-->search Paths -->Header Search Paths将路径/usr/include/libxml2添加到两个路径的后面