您的位置:首页 > 移动开发 > IOS开发

IOS中SAX和DOM解析XML<代码演示>

2014-03-14 00:00 141 查看
 

/*

 

     对于XML的解析方式大家所熟知的方式有两种:SAX<Simple API xml>和DOM <document>文档解析两种:

  下面就是大致数以下SAX和 DOM
的简单区别:

     

    1.SAX的解析方式以一种逐行解析的方式;XML文件都是以标签形式组成的比如:

     <?xml version="1.0" encoding="UTF-8"?>

         <students>

         <student>

         <name>张三</name>

         <gender>男</gender>

         <telephondeNumber>1234567891</telephondeNumber>

         </student>

         <student>

         <name>李四</name>

         <gender>男</gender>

         <telephondeNumber>1734995333</telephondeNumber>

         </student>

     </students>

 

     SAX解析是逐行读取,每一行读取完成后就会直接解析,程序可以较直观的看到每行数据,同时无需等到所有节点读取

     完成后,再将所有读取后的数据一次性返回,而是没读取一行记录一下数据,将数据返回;

 

    2.DOM解析,同样的XML文件DOM解析比较复杂,DOM解析的简单原理就是将XML文件中所有的节点标签,以树节点形式拼接,

      每读取一行,就将该数据载入到节点分支中,组成一个树状结构;逐步解析载入,直至最后一个叶子节点完成,当所有数据

      载入树状结构分支完成后,再将数据返回;因此,当中程序的等待时间较SAX解析来说慢了点;

 

    但是,对于小的程序来说这些微小的变化,不会影响太大;

 

    下面我们就来看看:SAX解析和DOM解析从概念上的区别:

     SAX与DOM之间的区别

     

     SAX与DOM之间有一些显著区别,包括:

 

       1.DOM是复杂对象处理的首选,比如当XML比较复杂的时候,或者当你需要随机处理文档中数据的时候。SAX从文档的开始通

          过每一节点移动,以定位一个特定的节点。

       2.DOM为载入到内存的文档节点建立类型描述。最终,这些描述呈现了可容易横向移动、潜在巨大、树型结构。如果XML很冗长,

         DOM就会显示出无法控制的胀大。例如,一个300KB的XML文档可以导致RAM或者虚拟内存中的3,000,000KB的DOM树型结构。

         通过比较就会发现,一个SAX文档根本就没有被解构,它也没有隐藏在内存空间中(当然当XML流被读入时,会有部分文档暂时隐

         藏在内存中)。SAX就是一种“更轻巧的”技术──它可以给你的系统带来更轻的负担。SAX相当于观看一场马拉松比赛,而DOM就好

         比邀请所有的比赛选手到家里参加晚餐。

       3.所以,你如何选择SAX和DOM?如果你处理复杂的东西,比如高级XSLT转换,或者Xpath过滤,请选择使用DOM。如果你建立或者
                      更改XML文档,你也可以选择DOM。

       4.相反,你可以使用SAX来查询或者阅读XML文档。SAX可以快速扫描一个大型的XML文档,当它找到查询标准时就会立即停止,然后
                    再处理之。在某些情况下,在一个方案中,最佳的选择是使用DOM和SAX处理不同的部分。例如,你可以使用DOM将XML载入到内存                  
    并改变它,然后通过从DOM树中发送一个SAX流而转移最后的结果。

     

     

     ---->SAX概念

      

         SAX是Simple API for XML的缩写,它并不是由W3C官方所提出的标准,可以说是“民间”的事实标准。实际上,它是一种社区
                       性质的讨论产物。虽然如此,在XML中对SAX的应用丝毫不比DOM少,几乎所有的XML解析器都会支持它。

         与DOM比较而言,SAX是一种轻量型的方法。我们知道,在处理DOM的时候,我们需要读入整个的XML文档,然后在内存中创建DOM
          树,生成DOM树上的每个Node对象。当文档比较小的时候,这不会造成什么问题,但是一旦文档大起来,处理DOM就会变得相当
                         费时费力。特别是其对于内存的需求,也将是成倍的增长,以至于在某些应用中使用DOM是一件很不划算的事(比如在applet            中)。这时候,一个较好的替代

         解决方法就是SAX。

     

         SAX在概念上与DOM完全不同。首先,不同于DOM的文档驱动,它是事件驱动的,也就是说,它并不需要读入整个文档,而文档的                        读入过程也就是SAX的解析过程。所谓事件驱动,是指一种基于回调(callback)机制的程序运行方法。(如果你对Java新的代
                       理事件模型比较清楚的话,就会很容易理解这种机制了)

     

         在XMLReader接受XML文档,在读入XML文档的过程中就进行解析,也就是说读入文档的过程和解析的过程是同时进行的,这和                            DOM区别很大。解析开始之前,需要向XMLReader注册一个ContentHandler,也就是相当于一个事件监听器,在
                                              ContentHandler中定义了很多方法,比

         如startDocument(),它定制了当在解析过程中,遇到文档开始时应该处理的事情。当XMLReader读到合适的内容,就会抛出                        相应的事件,并把这个事件的处理权代理给ContentHandler,调用其相应的方法进行响应

     

 */

#import "TableViewController.h"

#import "Students.h"

@interface
TableViewController ()
{
   NSString *_startElement;   
}

@end
@implementation TableViewController

//实例化xmlParser对象,并通过其初始化方法得到要解析的数据文件并完成解析
   NSXMLParser *xmlParser = [[NSXMLParseralloc]
initWithData:[selfloadFile]];

    //接收xmlParser协议
    xmlParser.delegate =self;

    /*-----------------------------------------------*/

    xmlParser.shouldProcessNamespaces =NO;//是否处理命名空间

    xmlParser.shouldReportNamespacePrefixes =NO;//是否通知命名空间前缀

    xmlParser.shouldResolveExternalEntities =NO;//是否处理外部标签实体

    //开始解析
    [xmlParserparse];

    /*-----------------------------------------------*/

//头文件---------------------------> SAX解析

#import <UIKit/UIKit.h>

#import "Students.h"

//让类遵守协议

@interface TableViewController :UITableViewController<NSXMLParserDelegate>//引入xml解析协议

@property(nonatomic,retain)NSMutableArray *stuArray;

//读取XML文件,将其转换为NSData文件格式

-(NSData *)loadFile;

@end

#pragma mark-实现自定义加载沙盒路径下XML文件方法-
-(NSData *)loadFile{

    

    //获取指定文件路径文件

       NSString *xmlPath = [NSStringstringWithContentsOfFile:[[NSBundlemainBundle]
pathForResource:@"student"ofType:@"xml"]encoding:NSUTF8StringEncodingerror:nil];
   NSLog(@"%@",xmlPath);

    //转换为NSData

    NSData *stuData = [xmlPathdataUsingEncoding:NSUTF8StringEncoding];

    
   return stuData;
}

#pragma mark--xmlParser Delegate实现协议方法--

//开始解析
-(void)parserDidStartDocument:(NSXMLParser *)parser{

    NSLog(@"%s",__FUNCTION__);

    self.stuArray = [NSMutableArrayarray];

    

}

//开始解析头一个标签
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString
*)qName attributes:(NSDictionary *)attributeDict{

    

    NSLog(@"%s",__FUNCTION__);
   NSLog(@"elementName=%@",elementName);

    
   if ([elementName
isEqualToString:@"student"]) {

        
       Students *xmlStu = [[Studentsalloc]
init];
        [self.stuArrayaddObject:xmlStu];
        [xmlSturelease],xmlStu =
nil;

        
    }
   _startElement = elementName;

    

    
}

//解析标签中的内容
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{

    

    NSLog(@"%s",__FUNCTION__);
   NSLog(@"string=%@",string);

//    if (![string isEqualToString:@"\n"]) {

    
       Students *findStu = [self.stuArraylastObject];

        if ([_startElementisEqualToString:@"telephondeNumber"])
{
            findStu.telephoneNumber = string;
        }
       else
if ([_startElementisEqualToString:@"name"]) {
            findStu.name = string;
        }
       else
if ([_startElementisEqualToString:@"gender"]) {
            findStu.gender = string;
        }

        

//    }

    

    
}

//解析结束标签
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{

    

    NSLog(@"%s",__FUNCTION__);

//    NSLog(@"elementName=%@",[self.stuArray]);

    _startElement =nil;
}

//接收解析,完成解析
-(void)parserDidEndDocument:(NSXMLParser *)parser{

    

    NSLog(@"%s",__FUNCTION__);

    NSLog(@"-------%@",[[self.stuArraylastObject]
name]);

    [self.tableViewreloadData];

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: