XML & JSON 简介
// 1. 开始解析XML文档
- (void)parserDidStartDocument:
// 2. 开始解析某个元素,会遍历整个XML,识别元素节点名称
- (void)parser:didStartElement:namespaceURI:qualifiedName:attributes:
// 3. 文本节点,得到文本节点里存储的信息数据,对于大数据可能会接收多次!为了节约内存开销
- (void)parser:foundCharacters:
// 4. 结束某个节点,存储从parser:foundCharacters:方法中获取到的信息
- (void)parser:didEndElement:namespaceURI:qualifiedName:
注意:在解析过程中,2、3、4三个方法会不停的重复执行,直到遍历完成为止
// 5. 解析XML文档结束
- (void)parserDidEndDocument:
// 6. 解析出错
- (void)parser:parseErrorOccurred:
实例代码
#import "DemoViewController.h"
#import
"UIImageView+WebCache.h"
#import "Video.h"
#import
"VideoCell.h"
#define kBaseURL
@"http://192.168.3.251/~apple"
@interface DemoViewController ()
<NSXMLParserDelegate>
{
NSMutableArray *_dataList;
UIImage
*_placeHolderImage;
//
以下是XML解析需要的成员变量
NSMutableString
*_elementString; // 拼接的字符串
Video
*_currentVideo; //
当前解析的视频模型对象
}
@end
@implementation
DemoViewController
/**
数据处理过程
1>
从服务器上加载不同类型的数据JSON/XML
2> 将接收到的数据转换成对象数组
3>
在表格中显示数组内容
XML解析的六个步骤
1.
开始解析文档,在这里做初始化工作
2.3.4会循环执行,一直到XML文档解析完毕
2. 解析一个节点
3.
查找节点内容,可能会多次
4. 节点完成
5. 解析完成,做收尾工作
6.
解析出错,清理中间数据
*/
- (void)viewDidLoad
{
[super
viewDidLoad];
// 设置标题
self.title
= (_loadType == kLoadDataJSON) ? @"JSON" : @"XML";
_placeHolderImage = [UIImage
imageNamed:@"user_default"];
if
(_loadType == kLoadDataJSON) {
[self loadJSON];
} else
{
[self
loadXML];
}
}
#pragma mark - 表格的数据源方法
-
(NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
return
_dataList.count;
}
- (UITableViewCell *)tableView:(UITableView
*)tableView cellForRowAtIndexPath:(NSIndexPath
*)indexPath
{
static NSString *ID =
@"MyCell";
VideoCell *cell = [tableView
dequeueReusableCellWithIdentifier:ID];
// 设置单元格
Video *video =
_dataList[indexPath.row];
cell.videoTitleLabel.text = video.name;
cell.teacherLabel.text = video.teacher;
cell.lengthLabel.text = video.lengthStr;
// 设置图像
//
完整的URL
NSString *imageURLStr = [NSString
stringWithFormat:@"%@%@", kBaseURL, video.imageURL];
NSURL
*url = [NSURL URLWithString:imageURLStr];
[cell.icon
setImageWithURL:url placeholderImage:_placeHolderImage];
return cell;
}
#pragma mark - 数据加载方法
-
(void)loadJSON
{
// 1. 从服务器获取数据
GET
// 1) url
NSURL *url = [NSURL
URLWithString:@"http://192.168.3.251/~apple/itcast/videos.php?format=json"];
// 2) request
NSURLRequest *request = [NSURLRequest
requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:2.0f];
// 3)
连接同步,可以让用户先有内容可看
NSError *error;
//
NSData存放的是二进制的数据
NSData *data = [NSURLConnection
sendSynchronousRequest:request returningResponse:nil
error:&error];
//
判断返回结果
if (data != nil)
{
//
正常返回数据
// NSString *result =
[[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];
//
NSLog(@"%@", result);
//
反序列化
NSArray *array =
[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments
error:nil];
NSLog(@"%@",
array);
//
技巧,从网络上接收到JSON,为了方便阅读,可以将其反序列化之后,保存至文件
[array writeToFile:@"/Users/apple/Desktop/123.plist"
atomically:YES];
//
将数据转换成模型,并保存至表格需要的数组中
NSMutableArray *arrayM = [NSMutableArray
arrayWithCapacity:array.count];
for (NSDictionary *dict in
array) {
Video *video = [[Video alloc]
init];
[video
setValuesForKeysWithDictionary:dict];
[arrayM addObject:video];
}
_dataList =
arrayM;
} else if (error == nil)
{
NSLog(@"返回空数据");
} else
{
NSLog(@"%@",
error.localizedDescription);
}
}
#pragma mark
解析XML
- (void)loadXML
{
// 1. 从服务器获取数据
GET
// 1) url
NSURL *url = [NSURL
URLWithString:@"http://192.168.3.251/~apple/itcast/videos.php?format=xml"];
// 2) request
NSURLRequest *request = [NSURLRequest
requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:2.0f];
// 3)
连接同步,可以让用户先有内容可看
NSError *error;
//
NSData存放的是二进制的数据
NSData *data = [NSURLConnection
sendSynchronousRequest:request returningResponse:nil
error:&error];
// 2.
XML解析
// 1) 解析器
NSXMLParser *parser
= [[NSXMLParser alloc] initWithData:data];
// 2)
设置代理
parser.delegate = self;
// 3)开始解析
[parser
parse];
}
#pragma mark - XML解析方法
// 1. 开始解析文档,在这里做初始化工作
-
(void)parserDidStartDocument:(NSXMLParser *)parser
{
NSLog(@"开始解析文档");
// 数组还没有被初始化,初始化数组
_dataList = [NSMutableArray array];
_elementString = [NSMutableString string];
}
//
2.3.4会循环执行,一直到XML文档解析完毕
// 2. 解析一个节点
- (void)parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName attributes:(NSDictionary
*)attributeDict
{
NSLog(@"节点开始 %@ %@", elementName,
attributeDict);
if ([elementName
isEqualToString:@"video"]) {
//
新建一个视频模型对象
_currentVideo = [[Video
alloc] init];
//
取视频ID
_currentVideo.videoId =
[attributeDict[@"videoId"] integerValue];
}
// 清空拼接字符串
[_elementString setString:@""];
}
// 3. 查找节点内容,可能会多次
-
(void)parser:(NSXMLParser *)parser foundCharacters:(NSString
*)string
{
NSLog(@"开始查找内容 %@",
string);
// 拼接字符串
[_elementString
appendString:string];
}
// 4. 节点完成
- (void)parser:(NSXMLParser
*)parser didEndElement:(NSString *)elementName namespaceURI:(NSString
*)namespaceURI qualifiedName:(NSString *)qName
{
NSLog(@"节点完成 %@ %p", elementName, _elementString);
NSString *result = [NSString
stringWithString:_elementString];
if ([elementName isEqualToString:@"video"])
{
//
对象的属性填充完毕,添加到数组
[_dataList
addObject:_currentVideo];
} else if ([elementName
isEqualToString:@"length"]) {
_currentVideo.length = [result integerValue];
} else if
(![elementName isEqualToString:@"videos"])
{
//
利用KVC给字符串类型的属性赋值
[_currentVideo
setValue:result forKey:elementName];
}
// else if ([elementName isEqualToString:@"name"])
{
// _currentVideo.name =
result;
// } else if ([elementName
isEqualToString:@"length"]) {
//
_currentVideo.length = [result integerValue];
// } else if
([elementName isEqualToString:@"videoURL"])
{
// _currentVideo.videoURL =
result;
// } else if ([elementName
isEqualToString:@"imageURL"]) {
//
_currentVideo.imageURL = result;
// } else if ([elementName
isEqualToString:@"desc"]) {
//
_currentVideo.desc = result;
// } else if ([elementName
isEqualToString:@"teacher"]) {
//
_currentVideo.teacher = result;
// }
}
// 5.
解析完成,做收尾工作
- (void)parserDidEndDocument:(NSXMLParser
*)parser
{
NSLog(@"解析完成");
NSLog(@"%@", _dataList);
}
// 6.
解析出错,清理中间数据
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError
*)parseError
{
NSLog(@"%@",
parseError.localizedDescription);
// 一旦解析发生错误,需要把解析过程中生成的记录全部清除,以免造成不必要的麻烦
[_dataList
removeAllObjects];
}
@end