/*
除了这两个txt格式的,还需要三个文件夹:SBJson,JSON,GDATA
message.txt
<?xml version = "1.0" encoding = "UTF-8"?>
<messages>
<message>
<sender>腾飞</sender>
<receiver>汪洋</receiver>
<content>今晚如家402,不见不散</content>
<date>2015年9月14日</date>
</message>
<message>
<data>2015.9.14</data>
<person>汪洋</person>
<content>蹦~汪洋傻逼</content>
</message>
</messages>
*/
/*
message2.txt
[
{
"sender" : "汪洋",
"receiver" : "凤姐",
"content" : "今晚如家402",
"date" : "2015年9月14日"
}
,
{
"sender" : "王铁柱",
"receiver" : "田二妞",
"content" : "今晚如家403",
"date" : "2015年9月14日"
}
]
一、 XML:用到一个开源解析类,GDataXMLNode(将其加入项目中),添加libxml2.dylib框架
经常用到的方法:
1.- (id)initWithXMLString:(NSString *)str options:(unsigned int)mask error:(NSError *)error
2.- (id)initWithData:(NSData *)data options:(unsigned int)mask error:(NSError *)error
这两个方法可以将NSString类型或者NSData类的数据转化为GDataXMLNode类可以解析的XML文档
3.- (GDataXMLElement *)rootElement 返回GDataXMLElement中所有节点信息
4.- (NSArray *)elementsForName:(NSString *)name 返回当前节点下名称为name的所有节点,返回值为数组。
5.- (NSString *)stringValue 返回节点中间的值。
二、 JSON:用到开源的框架SBJSON,对NSString类的扩展,我们程序中的所有NSString对象都可以调用其中的方法。
SBJSON的方法- (id)JSONValue 此方法返回一个ID类对象,因为JSON信息都是以键值来传输的,所以我们会用NSDictionary来接收这个返回值。
两种结构:
1.“键值对”的集合。对象(object),记录(Record),结构(struct),字典(dictionary),哈希表(hashtable),键列表(keyed list),关联数组(associative array)。
2.值的有序列表。数组(Array)。
*/
ViewController.m
#import "ViewController.h"
#import "Message.h"
#import "GDataXMLNode.h"
#import "JSONKit.h"
#import "SBJson.h"
@interface ViewController ()<NSXMLParserDelegate>
@property (nonatomic, strong) NSMutableArray * dataArray;
//用来拼接字符串
@property (nonatomic,strong) NSMutableString * appendString;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
//以下都是button点击事件
//1.SAX解析:逐行解析
- (IBAction)XMLSAX:(id)sender {
// mxl 是一种可扩展标记语言
// 由标签组成
// 标签成对出现
// 标签名自定
// SAX解析:逐行解析xml文件内容
// NSXMLParser
// 解析前先准备数据
NSString * filepath = [[NSBundle mainBundle] pathForResource:@"message" ofType:@"txt"];
// 打印出路径
NSLog(@"%@",filepath);
// url 给路径
NSURL * fileUrl = [[NSURL alloc]initWithString:filepath];
// data 转化成二进制文件
// NSData类型的都是二进制的东西
NSData * fileData = [NSData dataWithContentsOfFile:filepath];
// 创建解析器
NSXMLParser * parser = [[NSXMLParser alloc]initWithData:fileData];
// 设置代理
parser.delegate = self;
// 启动解析
[parser parse];
}
//2.GData解析:不适合解析数量大的数据,设计到效率问题
- (IBAction)XMLDOM:(id)sender {
// 准备路径
NSString * filePath = [[NSBundle mainBundle] pathForResource:@"message" ofType:@"txt"];
// 转成data类型
NSData * data = [NSData dataWithContentsOfFile:filePath];
// 创建GDataXML解析文档
GDataXMLDocument * xmlDoc = [[GDataXMLDocument alloc]initWithData:data options:0 error:nil];
// 获取根节点
GDataXMLElement * rootElement = xmlDoc.rootElement;
// 初始化数组
self.dataArray = [NSMutableArray array];
// 遍历查找
// GDataXMLelement是结点类型
// children是一个数组,数组中都是结点类型
for (GDataXMLElement * m1 in rootElement.children) {
// 创建model对象
Message * message = [[Message alloc]init];
// 遍历m1中的子节点
for (GDataXMLElement * m2 in m1.children) {
// KVC
// stringValue 就是结点之间的字符串
// name就是标签名
[message setValue:m2.stringValue forKey:m2.name];
}
// 将model对象存入数组
[self.dataArray addObject:message];
}
// 打印验证
for (Message * m in self.dataArray) {
NSLog(@"%@ %@ %@ %@",m.sender,m.receiver,m.content,m.date);
}
}
//3.一般用JSON解析,虽然结构不清晰,但是轻便好写
- (IBAction)JSONsystem:(id)sender {
// 准备路径
NSString * filePath = [[NSBundle mainBundle] pathForResource:@"message2" ofType:@"txt"];
// 转成data类型
NSData * data = [NSData dataWithContentsOfFile:filePath];
// json解析
// 错误
NSError * error = nil;
// JSON解析重点就这一句话:
NSArray * tempArray = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
NSLog(@"%@",tempArray);
// 初始化数组
self.dataArray = [NSMutableArray array];
for (NSDictionary * dict in tempArray) {
// 创建model对象
Message * m = [[Message alloc]init];
// 给model对象赋值
// KVC
// key和valued都是m中的
[m setValuesForKeysWithDictionary:dict];
// 将mod对象装入数组
[self.dataArray addObject:m];
}
// 打印验证
for (Message * m in self.dataArray) {
NSLog(@"%@ %@ %@ %@",m.sender,m.receiver,m.content,m.date);
}
}
//4.
- (IBAction)JSONKit:(id)sender {
// 准备路径
NSString * filePath = [[NSBundle mainBundle] pathForResource:@"message2" ofType:@"txt"];
// 转成data类型
NSData * data = [NSData dataWithContentsOfFile:filePath];
// 解析
NSArray * tempArray = [data objectFromJSONData];
NSLog(@"%@",tempArray);
// 转成model对象
self.dataArray = [NSMutableArray array];
for (NSDictionary * dict in tempArray) {
Message * m = [[Message alloc]init];
[m setValuesForKeysWithDictionary:dict];
[self.dataArray addObject:m];
}
// 打印验证
for (Message * m in self.dataArray) {
NSLog(@"%@ %@ %@ %@",m.sender,m.receiver,m.content,m.date);
}
}
// 作业:SBJson
- (IBAction)sbJson:(id)sender {
//准备路径
NSString * filePath = [[NSBundle mainBundle]pathForResource:@"message2.txt" ofType:nil];
//从路径的文件中读取字符串
NSString * s = [[NSString alloc]initWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
// NSLog(@"s = %@",s);
SBJsonParser * jsonParser = [[SBJsonParser alloc]init];
NSArray * jsonArray = [jsonParser objectWithString:s];
NSLog(@"arr = %@",jsonArray);
}
# pragma mark -- XMLParser 代理方法
//6个方法 (只用于xmlSax)
//1.开始解析文档
-(void)parserDidStartDocument:(NSXMLParser *)parser{
NSLog(@"开始解析文档");
// 做一些准备工作,例如初始化数组
self.dataArray = [NSMutableArray array];
}
//2.开始解析标签
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
NSLog(@"开始解析标签");
if ([elementName isEqualToString:@"message"]) {
// 创建model对象
Message * m = [[Message alloc]init];
// 存入数组
[self.dataArray addObject:m];
}
// 初始化拼接字符串
self.appendString = [NSMutableString string];
}
//3.获取文档
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
NSLog(@"获取文档");
// 该方法未必是一次取出整个字符串,有可能分成n段取出
// 拼接字符串
NSLog(@"%@",string);
[self.appendString appendString:string];
}
//4.结束标签解析
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
NSLog(@"结束解析标签");
// 先找到model对象(取最后一个对象)
Message *m = [self.dataArray lastObject];
// KVC
[m setValue:_appendString forKey:elementName];
// 使用完字符串,置空
self.appendString = nil;
/*
if ([elementName isEqualToString:@"sender"]) {
m.sender = _appendString;
}else if ([elementName isEqualToString:@"content"]){
m.content = _appendString;
}
*/
}
//5.结束解析文档
-(void)parserDidEndDocument:(NSXMLParser *)parser{
NSLog(@"结束解析文档");
for (Message * m in _dataArray) {
NSLog(@"sender : %@",m.sender);
NSLog(@"receiver : %@",m.receiver);
NSLog(@"content : %@",m.content);
NSLog(@"date : %@",m.date);
}
}
//6.当解析文档发生错误
-(void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError{
NSLog(@"当解析文档发生错误");
}
@end
Message.h
#import <Foundation/Foundation.h>
@interface Message : NSObject
//属性名和标签名一样,因为要用KVC
@property (nonatomic,copy) NSString * sender;
@property (nonatomic,copy) NSString * receiver;
@property (nonatomic,copy) NSString * content;
@property (nonatomic,copy) NSString * date;
@end
Message.m
#import "Message.h"
@implementation Message
//当查找到没有相应的key值会自动选择执行这个方法,否则程序崩溃
-(void)setValue:(id)value forUndefinedKey:(NSString *)key{
}
@end