XML解析方式及GData框架使用

一、概念

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

推荐阅读更多精彩内容