iOS ——XML数据结构及其两种解析数据的方式SAX 、DOM

1.解析的基本概念
所谓解析:从事先规定好的格式中提取数据
解析的前提:提前规定好格式、数据提供方按照格式提供数据、数据获取方则按照格式获取数据。
iOS 常见的解析:XML 解析、JSON 解析

2.XML 基本概念
XML:Extensible Markup language(可扩展标记语⾔言)主流数据格式之 一,可以用来存储和传输数据。
XML 数据格式的功能:数据交换、内存管理、用作配置文件。
XML 数据结构的语法
声明:
节点使用一对标签标示。其实结束标签。
根节点是起始节点,只有一个。节点可以嵌套。
节点可以有值。存储在一对标签中。

这里写图片描述
这里写图片描述

3.SAX 解析
1)SAX :Simple API for XML。基于事件驱动的解析⽅方式,逐⾏行解析 数据。(采⽤用协议回调机制)
2)NSXMLParser是iOS⾃自带的XML解析类。采⽤用SAX⽅方式解析数据。
3)解析过程由NSXMLParserDelegate协议⽅方法回调
4)解析过程:开始标签->取值->结束标签->取值
代码如下:
StudentInfor_XML.txt 文件

<students>  //根节点 开始标签
<student>   //根节点的子节点, name 的父节点
<name>懒洋洋</name>  //懒洋洋 :节点的值
<age>3</age>
<gender>male</gender>
<hobby></hobby>
<phone>128395069078</phone>
</student>

<student>
<name>懒洋洋1</name>
<age>3</age>
<gender>male</gender>
<hobby></hobby>
<phone>128395069078</phone>
</student>

<student>
<name>懒洋洋2</name>
<age>3</age>
<gender>male</gender>
<hobby></hobby>
<phone>128395069078</phone>
</student>

</students>  //节点的结束标签

XML解析步骤:
1、实例化NSXMLParser,传入从服务器接收的XML数据
2、定义解析器代理
3、解析器解析,通过解析代理方法完成XML数据的解析。
解析XML用到的的代理方法:
1. 开始解析XML文档
- (void)parserDidStartDocument:
2. 开始解析某个元素,会遍历整个XML,识别元素节点名称,如开头
-(void)parser:didStartElement:namespaceURI:qualifiedName:attributes:
3. 文本节点,得到文本节点里存储的信息数据。 节点中的数据XXXX
- (void)parser:foundCharacters:
4. 结束某个节点 如开头
- (void)parser:didEndElement:namespaceURI:qualifiedName:

注意:在解析过程中,2、3、4三个方法会不停的重复执行,直到遍历完成为止
5.解析XML文档结束
- (void)parserDidEndDocument:
6.解析出错
-(void)parser:parseErrorOccurred:

//存放model 对象的容器
@property (nonatomic, strong) NSMutableArray * array;
//当前节点
@property (nonatomic, strong) NSString * currentElement;


 #pragma mark XMLBUtton 的点击事件
 - (IBAction)xmlSAXAction:(id)sender {
 //  1. 获取文件路径
 NSString * path = [[NSBundle mainBundle]pathForResource:@"StudentInfor_XML" ofType:@"txt"];
 //    2.根据文件对象创建data 对象 (使用init 方法)
 NSData * data = [[NSData alloc] initWithContentsOfFile:path];
 //    3. 根据data 对象创建解析对象
 NSXMLParser * xmlparser = [[NSXMLParser alloc] initWithData:data];
 //    4. 设置代理
 xmlparser.delegate = self;
 //  5.开始解析 方法 - (BOOL)parse;
 [xmlparser parse];
 }

#pragma mark -  SAX 解析        SAX代理步骤---
#pragma mark - 1.开始文档解析
-(void)parserDidStartDocument:(NSXMLParser *)parser
{
//    开始文档解析的时候准备数组
//    数组里面存的是指针。
//    initWithCapacity 方法初始化 : 6 的倍数初始化。 刚开始6个。 放到7个的时候,12。13时候24。25的时候48. 减少数组在内存中的迁移。
    _array = [[NSMutableArray alloc] initWithCapacity:6];
}

#pragma mark 2. 开始标签解析
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
//    记录当前标签
    _currentElement = elementName;
//    根据标签student 建立model
    if ([elementName isEqualToString: @"student"]) {
//        此时添加到数组中的 student对象为空。解析出来时再添加对象的值
        Student * student = [Student new];
        [_array addObject:student];
    }
}
#pragma mark 3.获取标签内容
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    //获取数组最后一个元素 (获取数组中的随后一个元素,给最后一个元素赋值。如果是第一个元素赋值,会覆盖)
    Student * student = [_array lastObject];
//    KVC 赋值
    [student setValue:string forKey:_currentElement];
}

#pragma mark - 4. 结束标签解析
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    NSLog(@"结束标签解析");
//    当前存储点置为空, 不影响下次判断
    _currentElement = nil; 
}
#pragma mark 5.结束文档解析
-(void)parserDidEndDocument:(NSXMLParser *)parser
{
    NSLog(@"结束文档解析");
//    检验数据
    for (Student * student  in _array) {
        NSLog(@"%@",student);
        }
    }
#pragma mark 6. 错误处理
-(void) parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError
{
    NSLog(@"写错了,错误为%@",parseError);
}

总结:先开始文档解析,再开始标签解析。解析标签时,一个student 标签需要全部解析完在解析下一个,所以需要每次取出数组中Student * student = [_array lastObject]; 赋上解析的数据。

4.使用DOM 工具解析XML
DOM 解析
1)DOM:Document Object Model(⽂文档对象模型)。解析时需要
将XML⽂文件整体读⼊入,并重点内容且将XML结构化成树状,使⽤用时再通过树 状结构读取相关数据
2)GDataXMLNode是Google提供的开源XML解析类,对
libxml2.dylib进⾏行了Objective-C的封装
代码:

#pragma mark - XML DOM 解析 --

 - (IBAction)xmlDOMAction:(id)sender
 {
 //    1. 获取文件路径
 //    获取应用程序包
 NSBundle * bundle = [NSBundle mainBundle];
 //    通过包获取路径
 NSString * path = [bundle pathForResource:@"StudentInfor_XML" ofType:@"txt"];
 //    2. 根据文件路径获取data 对象 (使用遍历构造器方法)
 NSData * data = [NSData dataWithContentsOfFile:path];
 //    3. 根据datda 对象创建解析对象
 GDataXMLDocument * document = [[GDataXMLDocument alloc] initWithData:data options:0 error:nil];
 //    4.获取根节点 (本题中<students>)
 GDataXMLElement * rootElement = [document rootElement];
 //   初始化数组,开辟空间(开辟6个指针大小的空间,给array)
 _array = [[NSMutableArray alloc]initWithCapacity:6];
// 遍历根节点的孩子节点 ,获取每个孩子节点(<student>) 
for (GDataXMLElement * subEement in rootElement.children) {
 //创建对象
 Student * student = [Student new];
 for (GDataXMLElement * element in subEement.children) {
//遍历 孩子节点的孩子节点,获取每个孩子节点的值。并给student 的各个属性赋值。
 [student setValue:element.stringValue forKey:element.name];
 }
 //        添加到数组中
 [_array addObject:student];
 }
 //    校验
 for (Student * student  in _array) {
 NSLog(@"%@",student);
 }
 }

总结:iOS 中对XML 文件的解析方法有两种:DOM 、SAX
比较:
1.SAX方法可以使用iOS SDK中的NSXMLParser,DOM方法可以使用GOOGLE提供的GDataXML。
2、SAX(SimpleAPI for XML)
只能读,不能修改,只能顺序访问,适合解析大型XML,解析速度快
常应用于处理大量数据的XML,实现异构系统的数据访问,实现跨平台
从文档的开始通过每一节点移动,定位一个特定的节点
3、DOM(DocumentObject Model)
不仅能读,还能修改,而且能够实现随机访问,缺点是解析速度慢,适合解析小型文档.方便操作.
在内存中生成节点树操作代价昂贵。

详细理解:
DOM将整个xml看成是一个树状的结构,在解析的时候,会将整个xml文件加载到我们的内存当中,然后通过DOM提供的API来对我们的xml数据进行解析,这种方式解析xml非常的方便,并且我们可以通过某个节点访问到其兄弟或者是父类、子类节点。
不好的地方就是,其会将整个xml文档加载到内存中,这样会大大的占用我们的内存资源,对于手机来说,内存资源是非常非常宝贵的。
SAX相对于DOM 速度慢但是占用内存小,非常适合用于移动设备。 SAX解析XML文件采用的是事件驱动,也就是说,它并不需要解析完整个文档,在按内容顺序解析文档的过程中,SAX会判断当前读到的字符是否合法XML语法中的某部分,如果符合就会触发事件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值