XML解析方式及GData框架使用

作者: 我是滕先生 | 来源:发表于2016-03-12 10:02 被阅读842次

    一、概念

    1、XML概念:
    Extensible Markup Language(可扩展标记语言)
    HTML (超文本标记语言)

    非常类似于HTML,HTML的作用是显示数据,XML的目的是存储和传输数据
    XML是以前各种应用之间传输数据最常用的格式
    W3C的推荐标准

    2、语法

    <Class className="三年一班">
    <Person color="yellow" weight="130" height="150">
        <name>wg</name>
        <age>108</age>
    </Person>
    <Student  name="y" />
    </Class>
    

    (1)有且只能有一个根节点!!!根节点就是最外面的那个标签,Class就是根节点
    (2)注释:
    (3)可以添加一个属性后直接结束 <Student name="y" />


    二、XML解析SAM方式(只读)

    XML格式的解析方式

    SAX :iOS上解析,速度快,内存占用小,只读
    DOM : mac上的解析方式,iOS无法直接使用,解析过程中内存占用大,读写

    SAX的解析步骤:

    1. 加载xml数据
    2. 找开始节点(包括节点的属性)
    3. 找节点之间的内容
    4. 找结束节点
    5. 重复2、3、4步骤,直到最后一个节点,解析结束

    例子:解析XML文档到模型中

    注意:KVC的所有属性要用copy,不然拼接字符串会导致模型的值为空(因为KVC只是改变指针指向,而不是赋值)

    @property (nonatomic, strong) NSMutableArray *videos;(懒加载)
    //当前创建的video对象
    @property (nonatomic, strong) Video *currentVideo;
    //存储当前节点的内容
    @property (nonatomic, copy) NSMutableString *mString;(懒加载)
    

    1.加载数据

    注意:所有代理方法是和设置代理属性时的线程(parser.delegate = self)在一个线程上!!!

    //解析数据
    NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
    //设置代理
    parser.delegate = self;
    //开始执行代理的方法,代理的方法中开始解析的
    [parser parse];
    

    2.实现代理方法:
    (1)开始解析文档时执行

    - (void)parserDidStartDocument:(NSXMLParser *)parser {
    }
    

    (2)找开始节点时执行

    参数:
    elementName 标签的名称
    attributeDict 标签的属性

    - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict {
    //如果是video标签,创建video对象
    if ([elementName isEqualToString:@"video"]) {
        self.currentVideo = [[Video alloc] init];
        self.currentVideo.videoId = @([attributeDict[@"videoId"] intValue]);
        //添加到数组中
        [self.videos addObject:self.currentVideo];
    }
    }
    

    3.找节点之间的内容时执行

    注意:找内容过程中该方法可能执行多次!!!所以要拼接字符串

    - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    //拼接字符串
    [self.mString appendString:string];
    }
    

    (4)找结束节点时执行

    - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    //判断标签是否是对应的属性
    if (![elementName isEqualToString:@"video"] && ![elementName isEqualToString:@"videos"]) {
        //self.currentVideo.length =
        //kvc 赋值的过程就是地址指向的过程,不会做类型转换
        [self.currentVideo setValue:self.mString forKey:elementName];
    }
    //清空可变字符串
    [self.mString setString:@""];
    }
    

    (5)结束解析文档时执行

    - (void)parserDidEndDocument:(NSXMLParser *)parser {
    NSLog(@"%@",self.videos);
    }
    

    (6)解析出错时执行

    - (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
    }
    

    三、DOM方式解析(可读写)

    DOM方式的解析 Document Object Model
    DOM--文档对象模型(文档树模型)
    一次性把xml全部加载到内存,内存消耗大
    之前的SAX方式只能读取XML,DOM可以修改,添加删除修改节点
    iOS默认不支持DOM解析(不支持NSXML这个类),在iOS解析DOM的话需要第三方框架:GData/KissXML(XMPP中使用此框架)
    适合读写比较小的XML文件
    GData项目地址:https://github.com/graetzer/GDataXML-HTML

    GData第三方框架使用:

    (1)搜索Header Search Paths
    复制路径添加到这里 /usr/include/libxml2


    搜索Header Search Paths

    (2)添加标识
    搜索 Other Linker Flags ,复制 -lxml2 添加到这里


    添加标识

    概念:

    节点Node:XML中所有内容都是节点,包括标签、属性、注释、文本内容等。
    元素Element:表示一个标签,包括标签本身(标签名字和标签内容(内容可能是子标签))和标签的属性(属性名字和属性内容),Element继承于Node

    框架中的三个类:
    GDataXMLDocument
    GDataXMLNode
    GDataXMLElement

    框架中类的结构
    框架中类的常用属性

    使用步骤:XML解析转模型方法

    待解析的源数据

    1.加载XML数据到GDataXMLDocument对象中

    GDataXMLDocument *document = [[GDataXMLDocument alloc] initWithData:data error:NULL];
    

    2.获取xml文档的根元素(根元素包括videos标签内的所有内容,即XML的所有内容)

    GDataXMLElement *rootElement = document.rootElement;
    

    3、遍历二级video节点

    NSMutableArray *mArray = [NSMutableArrayarrayWithCapacity:10];
    //遍历所有的video节点
    for (GDataXMLElement *element in rootElement.children) {
        //创建一个模型对象,添加到模型数组中
        Video *v = [[Video alloc] init];
        [mArray addObject:v];
        //遍历每个video的子标签
        for (GDataXMLElement *subElement in element.children) {
            //给模型KVC赋值
            [v setValue:subElement.stringValue forKey:subElement.name];
        }
        //遍历video的所有属性(包括video标签自己的属性)
        for (GDataXMLNode *attr in element.attributes) {
            [v setValue:attr.stringValue forKey:attr.name];
        }
    }
    NSLog(@"%@",mArray);
    

    四、GData写入功能,生成XML

    该功能可将原生文本输入转换为HTML,例如下面面试小demo(有空再上传):


    面试小demo

    使用方法:

    // 创建一个标签元素  
    GDataXMLElement *element = [GDataXMLNode elementWithName:@"user" stringValue:@"will"];  
    // 创建一个属性  
    GDataXMLElement *attribute = [GDataXMLNode attributeWithName:@"a" stringValue:@"b"];  
      
    // 创建一个根标签  
    GDataXMLElement *rootElement = [GDataXMLNode elementWithName:@"root"];  
    // 把标签与属性添加到根标签中  
    [rootElement addChild:element];  
    [rootElement addAttribute:attribute];  
      
    // 生成xml文件内容  
    GDataXMLDocument *xmlDoc = [[GDataXMLDocument alloc] initWithRootElement:rootElement];  
    NSData *data = [xmlDoc XMLData];  
    NSString *xmlString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];  
    NSLog(@"%@", xmlString);  
    

    NSLog输出为:

    <?xml version="1.0"?>  
    <root a="b"><user>will</user></root> 
    

    相关文章

      网友评论

      • 594a7caa3baf:在xml文件加入:
        <a. .....\>
        hello world
        <b. ......\>
        其中hello word部分不被解析,也可以理解为注释,我的理解对吗

      本文标题:XML解析方式及GData框架使用

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