解析XML

作者: 锦鲤跃龙 | 来源:发表于2017-09-08 09:43 被阅读0次

    解析方式

    • 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(@"发生错误");
        
    }
    

    相关文章

      网友评论

          本文标题:解析XML

          本文链接:https://www.haomeiwen.com/subject/uqkgjxtx.html