解析XML
2017-09-08 本文已影响0人
锦鲤跃龙
解析方式
- DOM MAC提供的解析方法 (Document Object Model ,文档对象模型。解析时需要将XML文件整体读入,并且将XML结构化成树状,使用时再通过树状结构读取相关数据,查找特定节点,然后对节点进行读或写,iOS中无法直接使用
- 原因:内存开销巨大!
- 可读可写
- 将数据已树形结构加载到内存
- SAX iOS提供的解析方式 (Simple API for XML,基于事件驱动的解析方式,逐行解析数据,采用协议回调机制)
- 内存开销小
- 只读
- 速度快
- 从上到下,顺序解析的过程
解析思路
- 打开文档(准备)
- 开始节点
- 发现节点内容(一个节点内容,可能会读取很多次!)(内容是节点回到2)
- 结束节点
- 文档解析完成!
解析方法
-
NSXMLParse:开发用这个官方
-
苹果原生,SAX方式解析,它基于事件通知的模式,一边读取文档一边解析数据,不用等待文档全部读入以后再解析,所以如果你正打印解析的数据,而解析过程中间出现了错误,那么在错误节点之间的数据会正常打印,错误后面的数据不会被打印。解析过程由NSXMLParserDelegate协议方法回调。
-
第三方框架
-
libxml2:纯C语言框架,默认包含在iOS SDK,同时支持DOM 和SAX解析
-
GDataXMl:谷歌开发 ,基于libxml2,支持DOM解析
思维导图
这里写图片描述解析代码
//1.可变数组
@property(nonatomic,strong)NSMutableArray *videos;
//2.当前解析的节点模型
@property(nonatomic,strong)Video *currentVideo;
//3.拼接字符串--可变字符串
@property(nonatomic,strong)NSMutableString *elementStr;
@end
@implementation ViewController
-(NSMutableArray *)videos
{
if (!_videos) {
_videos = [[NSMutableArray alloc]init];
}
return _videos;
}
-(NSMutableString *)elementStr
{
if (!_elementStr) {
_elementStr = [[NSMutableString alloc]init];
}
return _elementStr;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self loadData];
}
//MARK -- XML解析
- (void)loadData {
//1.url
NSURL *url = [NSURL URLWithString:@"http://localhost:8080/videos.xml"];
//2.request
NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:1 timeoutInterval:10.0];
//3.发现请求
[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc]init] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
// //XML解析 是一个耗时操作!
// NSXMLParser *parser = [[NSXMLParser alloc]initWithData:data];
//
// //设置代理 -旦解析器开始解析,后续的工作就会由代理来监听
// parser.delegate = self;
//
//
// //解析器解析
// [parser parse];
NSXMLParser* paraser = [[NSXMLParser alloc] initWithData:data];
paraser.delegate = self;
[paraser parse];
}];
}
#pragma mark --<XML解析代理方法>
//1.打开文档
-(void)parserDidStartDocument:(NSXMLParser *)parser
{
NSLog(@"1.开始文档");
//1.清空数组
[self.videos removeAllObjects];
}
//2.开始节点
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict
{
//elementName 节点名称
//namespaceURI 命名空间
//qualifiedName 命名空间限定的本地名称
//attributes 属性
NSLog(@"2.开始节点 %@ %@",elementName,attributeDict);
if ([elementName isEqualToString:@"video"]) {
//1.新建模型
self.currentVideo = [[Video alloc]init];
//2设置videoID的属性
self.currentVideo.videoId = @([attributeDict[@"videoId"]intValue]);
}
}
//3.发现节点内容
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
//拼接字符串
NSLog(@"==> %@",string);
[self.elementStr appendString:string];
}
//4.结束节点
/*
kvc
*/
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
NSLog(@"4.结束节点:%@",elementName);
if ([elementName isEqualToString:@"video"]) {
[self.videos addObject:self.currentVideo];
}else if (![elementName isEqualToString:@"videos"])
{
[self.currentVideo setValue:self.elementStr forKey:elementName];
}
//清空字符串
[self.elementStr setString:@""];
}
//5.结束解析
-(void)parserDidEndDocument:(NSXMLParser *)parser
{
NSLog(@"5.结束解析!%@",self.videos);
}
//6.出现错误(主要是网络开发,就需要对出错进行处理)
-(void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError
{
NSLog(@"发生错误");
}