解析XML

解析方式

  • DOM MAC提供的解析方法 (Document Object Model ,文档对象模型。解析时需要将XML文件整体读入,并且将XML结构化成树状,使用时再通过树状结构读取相关数据,查找特定节点,然后对节点进行读或写,iOS中无法直接使用
    • 原因:内存开销巨大!
    • 可读可写
    • 将数据已树形结构加载到内存
  • SAX iOS提供的解析方式 (Simple API for XML,基于事件驱动的解析方式,逐行解析数据,采用协议回调机制)
    • 内存开销小
    • 只读
    • 速度快
    • 从上到下,顺序解析的过程

解析思路

  1. 打开文档(准备)
  2. 开始节点
  3. 发现节点内容(一个节点内容,可能会读取很多次!)(内容是节点回到2)
  4. 结束节点
  5. 文档解析完成!

解析方法

  • 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(@"发生错误");
    
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,458评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,454评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,171评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,062评论 0 207
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,440评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,661评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,906评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,609评论 0 200
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,379评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,600评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,085评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,409评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,072评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,088评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,860评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,704评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,608评论 2 270

推荐阅读更多精彩内容