zoukankan      html  css  js  c++  java
  • IOS 解析XML数据

    ●  什么是XML

    ●  全称是Extensible Markup Language,译作可扩展标记语言

    ●  JSON一样,也是常用的一种用于交互的数据格式

    ●  一般也叫XML文档(XML Document)


    五、XML ====================总结============================
    1.语法
    1> 文档声明
    <?xml version="1.0" encoding="UTF-8" ?>

    2> 元素
    3> 属性
    <videos>
        <video name="小黄人 第01部" length="10"/>
        <video name="小黄人 第01部" length="10"/>
    </videos>
    * videos和video是元素(节点)
    * name和length叫做元素的属性
    * video元素是videos元素的子元素

    2.解析
    1> SAX解析:逐个元素往下解析,适合大文件
    * NSXMLParser

    2> DOM解析:一口气将整个XML文档加载进内存,适合小文件,使用最简单
    * GDataXML
    ==================================================
     

    XML的解析方式有2

    DOM:一次性将整个XML文档加载进内存,比较适合解析文件(常用方式

    - (NSArray *)parseJSONData:(NSData *)data
    {
        // 解析数据
        NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
        NSArray *array = dict[@"videos"];
        
        NSMutableArray *videos = [NSMutableArray array];
        for (NSDictionary *videoDict in array) {
            HMVideo *video = [HMVideo videoWithDict:videoDict];
            [videos addObject:video];
        }
        return videos;
    }
    View Code

     SAX:从根元素开始,按顺序一个元素一个元素往下解析,比较适合解析文 件

     

    iOS中,解析XML的手段有很多
    苹果原生
    NSXMLParser:SAX方式解析,使用简单

    第三方框架

    libxml2:纯C语言,默认包含在iOS SDK中,同时支持DOMSAX方式解析

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

    XML解析方式的选择建议
    大文件:NSXMLParserlibxml2 小文件:GDataXML

    NSXMLParser

    使用步骤
    // 传入XML数据,创建解析器
    NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data]; // 设置代理,监听解析过程
    parser.delegate = self;
    // 开始解析
    [parser parse];

    NSXMLParser采取的是SAX方式解析,特点是事件驱动,下面情况都会通知代理

    当扫描到文档(Document)的开始与结束
    当扫描到元素(Element)的开始与结束

    - (NSArray *)SAXparseXMLWithData:(NSData *)data
    {
        // 1.创建解析器
        NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
        
        // 2.设置代理
        parser.delegate = self;
        
        // 3.开始解析
        [parser parse]; // 卡住(解析完毕才会返回)
        
        return self.videos;
    }
    View Code

    NSXMLParserDelegate

    当扫描到文档的开始时调用(开始解析)
    - (void)parserDidStartDocument:(NSXMLParser *)parser

     ● 当扫描到文档的结束时调用(解析完毕)
    - (void)parserDidEndDocument:(NSXMLParser *)parser

    当扫描到元素的开始时调用(attributeDict存放着元素的属性)

    - (void)parser:(NSXMLParser *)parser didStartElement:(NSString
    *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:
    (NSString *)qName attributes:(NSDictionary *)attributeDict
    

    当扫描到元素的结束时调用

    - (void)parser:(NSXMLParser *)parser didEndElement:(NSString
    *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:
    (NSString *)qName
    
    #pragma mark - NSXMLParserDelegate
    /**
     *  开始解析文档时调用
     */
    - (void)parserDidStartDocument:(NSXMLParser *)parser
    {
        //    NSLog(@"parserDidStartDocument----");
    }
    /**
     *  结束解析文档时调用(解析完毕)
     */
    - (void)parserDidEndDocument:(NSXMLParser *)parser
    {
        //    NSLog(@"parserDidEndDocument----");
    }
    
    /**
     *  解析到一个元素的开头时调用 <videos>
     */
    - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
    {
        //    NSLog(@"didStartElement----%@", elementName);
        if ([@"videos" isEqualToString:elementName]) { // 解析到一个videos标签
            self.videos = [NSMutableArray array];
        } else if ([@"video" isEqualToString:elementName]) { // 解析到一个video标签, 创建一个模型
            HMVideo *video = [HMVideo videoWithDict:attributeDict];
            [self.videos addObject:video];
        }
    }
    
    /**
     *  解析到一个元素的结尾时调用 </videos>
     */
    - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
    {
        //    NSLog(@"didEndElement----%@", elementName);
    }
    View Code
    
    

    GDataXML配置

    GDataXML基于libxml2库,得做以下配置
    导入libxml2
    设置libxml2的头文件搜索路径(为了能找到libxml2库的所有头文件) Head Search Path中加入/usr/include/libxml2

    设置链接参数(自动链接libxml2库) Other Linker Flags中加入-lxml2

    由于GDataXML是非ARC的,因此得设置编译参数

     

    GDataXML使用(常用方式

    GDataXML中常用的类
    GDataXMLDocument:代表整个XML文档

     ● GDataXMLElement 代表文档中的每个元素

    使用attributeForName:方法可以获得属性值

    - (NSArray *)DOMparseXMLWithData:(NSData *)data
    {
        // 1.加载文档
        GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:data options:0 error:nil];
        
        // 2.获得根元素
        GDataXMLElement *root = doc.rootElement;
        
        // 3.获得所有video元素
        NSArray *elements = [root elementsForName:@"video"];
        
        // 4.将GDataXMLElement对象转成HMVideo模型
        NSMutableArray *videos = [NSMutableArray array];
        for (GDataXMLElement *ele in elements) {
            HMVideo *video = [[HMVideo alloc] init];
            video.ID = [ele attributeForName:@"id"].stringValue.intValue;
            video.length = [ele attributeForName:@"length"].stringValue.intValue;
            video.name = [ele attributeForName:@"name"].stringValue;
            video.image = [ele attributeForName:@"image"].stringValue;
            video.url = [ele attributeForName:@"url"].stringValue;
            [videos addObject:video];
        }
        return videos;
    }
    View Code

    调用XML 类

    @implementation HMVideoTool
    
    - (NSArray *)parseXMLData:(NSData *)data
    {
        return [self DOMparseXMLWithData:data];
    }
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        
        // 去除分割线
        self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
        
        [MBProgressHUD showMessage:@"正在加载视频信息...."];
        
        // 访问服务器数据
        NSString *urlStr = @"http://192.168.1.200:8080/MJServer/video?type=XML";
        
        // 发送请求
        NSURL *url = [NSURL URLWithString:urlStr];
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; // GET
        request.timeoutInterval = 10;
        
        [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
            // 隐藏
            [MBProgressHUD hideHUD];
            
            if (data) {
                // 解析数据 data : XML数据
                HMVideoTool *tool = [[HMVideoTool alloc] init];
                self.videos = [tool parseXMLData:data];
                // 刷新表格
                [self.tableView reloadData];
            } else {
                [MBProgressHUD showError:@"网络繁忙!!!"];
            }
        }];
    }
     
  • 相关阅读:
    第一个爬虫和测试
    数学规律
    自定义手绘
    tqqqy的成绩表
    Linux常用命令-netstat
    文档查看命令 cat more less tail head
    Linux三剑客-常用命令
    IO多路复用模型
    redis 的线程模型
    为什么需要缓存?
  • 原文地址:https://www.cnblogs.com/liuwj/p/6607970.html
Copyright © 2011-2022 走看看