zoukankan      html  css  js  c++  java
  • iOS 中的 xml 解析

    在ios 中解析xml 的方法有很多种

    1.苹果原生

    NSXMLParser:SAX方式解析,使用简单

    2.第三方框架

    libxml2:纯c语言,默认包含在ios  sdk中,同时支持DOM 和 SAX 方式解析

    GDataXML : DOM方式解析,由谷歌开发,基于libxml2

    xml 解析建议方式:

    大文件选用:NSXMLParser   或者 libxml2

    小文件选用:GDataXML

    xml解析:

    SAX方式解析:

       从上往下,一点一点解析,性能比较好,也是苹果推荐使用的。

    DOM方式解析

      一次性将xml文档以树形结构读入内存,内存消耗比较大。适用于比较小的xml文件解析。在ios 开发中默认是不支持这种方式的解析。但是有一些第三方框架实现了这个方式,

    KissXML & GData 都是采用DOM解析。

    //
    //  ViewController.m
    //  04-xml解析
    //
    //  Created by jerry on 15/9/28.
    //  Copyright (c) 2015年 jerry. All rights reserved.
    //
    
    #import "ViewController.h"
    #import "Video.h"
    @interface ViewController ()<NSXMLParserDelegate>
    /**
     *  整个xml的数据容器
     */
    @property(nonatomic,strong)NSMutableArray *videos;
    
    /**
     *  第三步拼接字符串
     */
    @property(nonatomic,strong)NSMutableString *elementString;
    /**
     *  当前模型
     */
    @property(nonatomic,strong)Video *currentVideo;
    /**
     *  专门用来存储表格所有的数据,也就是表格数据源
     */
    @property(nonatomic,strong)NSMutableArray *dataList;
    @end
    
    @implementation ViewController
    @synthesize videos = _videos;
    - (void)setDataList:(NSMutableArray *)dataList
    {
        _dataList = dataList;
        // 只要重新赋值  就要刷新
        [self.tableView reloadData];
        // 隐藏刷新控件
        [self.refreshControl endRefreshing];
    }
    /**
     *  懒加载  初始化 自定义属性
     
     */
    -(NSMutableArray *)videos
    {
        if (_videos == nil) {
            _videos = [NSMutableArray array];
        }
        return _videos;
    }
    /**
     *  懒加载  初始化 自定义属性
     *
     *  @return <#return value description#>
     */
    - (NSMutableString *)elementString
    {
        if (_elementString == nil) {
            _elementString = [NSMutableString string];
        }
        return _elementString;
    }
    //- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    //    [self loadData];
    //}
    -(void)loadView
    {
        [super loadView];
        
        [self loadData];
    }
    /**
     *  加载xml  数据
     *  从第2步到第4步,可以拿到video的属性。
     */
    - (IBAction)loadData
    {
        // 1.url
        NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/videos.xml"];
        
        // 2.请求
        // 不采用这个请求的原因就是因为他会有缓存,每次加载会先找缓存数据,这样就会出现“幻觉”数据。
        // NSURLRequest *request = [NSURLRequest requestWithURL:url];
        
        // 这样的请求 可以避免缓存数据,以免数据更改了 刷新ui 的时候还是显示原来的数据。
        NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:2.0f];
        
        
        // 3.连接
        [NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc]init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
            // xml 解析
            
            // 1.实例化xml 解析器
            NSXMLParser *parser = [[NSXMLParser alloc]initWithData:data];
            
            // 2.设置代理
            parser.delegate = self;
            
            // 3.开始解析
            [parser parse];
            
            
        }];
    }
    #pragma mark - 代理方法
    /**
     *   1.打开文档 准备开始解析
     *
     *  @param parser <#parser description#>
     */
    - (void)parserDidStartDocument:(NSXMLParser *)parser
    {
        NSLog(@"打开文档");
        // 初始化数组容器,清空容器,便于多次加载数据
        [self.videos removeAllObjects];
    }
    
    /**
     *  2.开始节点
     *  新建一个video对象,设置video的属性,
     *  @param parser        <#parser description#>
     *  @param elementName   元素名称
     *  @param namespaceURI  <#namespaceURI description#>
     *  @param qName         <#qName description#>
     *  @param attributeDict <#attributeDict description#>
     */
    - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
    {
        NSLog(@"开始节点---%@---%@",elementName,attributeDict);
        
        // 如果开始节点的名称是video 就创建一个对象。
        if ([elementName isEqualToString:@"video"]) {
            self.currentVideo =[[Video alloc]init];
            // 设置videoid
            self.currentVideo.videoId = attributeDict[@"videoId"];
        }
        // 清空字符串内容 因为马上要进行第3步,开始拼接当前节点内容
        [self.elementString setString:@""];
    }
    /**
     *  3.发现节点里面内容
     *
     *  @param parser <#parser description#>
     *  @param string <#string description#>
     */
    - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
    {
        NSLog(@"发现节点内容---%@",string);
        // 开始拼接
        [self.elementString appendString:string];
    }
    /**
     *  4.结束节点
     *
     *  @param parser       <#parser description#>
     *  @param elementName  <#elementName description#>
     *  @param namespaceURI <#namespaceURI description#>
     *  @param qName        <#qName description#>
     */
    - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
    {
        NSLog(@"结束节点---%@",elementName);
        if ([elementName isEqualToString:@"video"]) {
            //  如果结束节点是video 需要把这个对象添加到数组
            [self.videos addObject:self.currentVideo];
        }else if (![elementName isEqualToString:@"videos"])
        {
            // 利用kvc 进行赋值。可以省略注释掉的代码的麻烦。
            [self.currentVideo setValue:self.elementString forKeyPath:elementName];
        }
        
    //    // 如果结束节点,就可以把第二步创建的对象进行赋值,设置name/length属性
    //    else if ([elementName isEqualToString:@"name"]) {
    //        // 设置name 属性
    //        self.currentVideo.name = self.elementString;
    //        
    //    }else if ([elementName isEqualToString:@"length"])
    //    {
    //        // 设置length属性
    //        // @([self.elementString integerValue]) 现将字符串转成 数字,然后再将数字专程number
    //        self.currentVideo.length = @([self.elementString integerValue]);
    //        
    //    }
    }
    /**
     *  5.结束文档
     *
     *  @param parser <#parser description#>
     */
    - (void)parserDidEndDocument:(NSXMLParser *)parser
    {
        NSLog(@"结束文档");
        // xml  真正解析结束 可以在主线程更新ui
        dispatch_async(dispatch_get_main_queue(), ^{
            self.dataList =self.videos;
        });
    }
    
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        return  self.videos.count;
    }
    - (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
        
        Video *video = self.dataList[indexPath.row];
        
        cell.textLabel.text = video.name;
        
        return cell;
    }
    
    
    
    
    
    
    
    
    @end
  • 相关阅读:
    如何关闭微软反恶意软件客户端
    年轻爸爸家长会上猝死,事前已连续发烧三天
    人猝死前身体发出两个救命信号,一定要清楚,关键时刻救命
    火遍世界的视力恢复法 现在知道还不晚!
    重视工龄工资,食堂一定自己办
    VR行业纷纷倒闭:有硬件没内容
    企业为什么要去美国建厂
    bzoj 1046 : [HAOI2007]上升序列 dp
    bzoj 1857: [Scoi2010]传送带 三分
    bzoj 1045: [HAOI2008] 糖果传递
  • 原文地址:https://www.cnblogs.com/pengpengzhang/p/4843594.html
Copyright © 2011-2022 走看看