XML的两种解析方式逐行解析(SAX解析)节点解析(DOM解析);

前端之家收集整理的这篇文章主要介绍了XML的两种解析方式逐行解析(SAX解析)节点解析(DOM解析);前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

SAX逐行解析

SAXSimpleAPIfor XML。基于事件驱动的解析方式,逐行解析数据。(采用协议回调机制)

NSXMLParseriOS自带XML解析类。采用SAX方式解析数据

解析过程由NSXMLParserDelegate协议方法回调

解析过程:开始标签->取值->结束标签->取值

DOM解析

DOMDocumentObjectModel(文档对象模型)。解析时需要将XML文件整体读入,并且将XML结构化成树状,使用时再通过树状结构读取相关数据

GdataxMLNode(这个类在下载包里面)Google提供的开源XML解析类,对libxml2.dylib进行了ObjectiveC的封装

采用DOM方式解析数据

iOS中包含一个C语言的动态链接libxml2.dylib,解析速度比NSXMLParser

AppDelegate.m
#import"AppDelegate.h"
#import"MainViewController.h"
@implementationAppDelegate
-(BOOL)application:(UIApplication*)applicationdidFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
self.window=[[UIWindowalloc]initWithFrame:[[UIScreenmainScreen]bounds]];
//Overridepointforcustomizationafterapplicationlaunch.
self.window.backgroundColor=[UIColorwhiteColor];
[self.windowmakeKeyAndVisible];


MainViewController*mainVC=[[MainViewControlleralloc]init];
UINavigationController*naviVC=[[UINavigationControlleralloc]initWithRootViewController:mainVC];
self.window.rootViewController=naviVC;
[naviVCrelease];
[mainVCrelease];

[_windowrelease];
returnYES;
}
-(void)dealloc
{
[_windowrelease];
[superdealloc];
}
-(void)applicationWillResignActive:(UIApplication*)application
{
//Sentwhentheapplicationisabouttomovefromactivetoinactivestate.Thiscanoccurforcertaintypesoftemporaryinterruptions(suchasanincomingphonecallorSMSmessage)orwhentheuserquitstheapplicationanditbeginsthetransitiontothebackgroundstate.
//UsethismethodtopauSEOngoingtasks,disabletimers,andthrottledownOpenGLESframerates.Gamesshouldusethismethodtopausethegame.
}
-(void)applicationDidEnterBackground:(UIApplication*)application
{
//Usethismethodtoreleasesharedresources,saveuserdata,invalidatetimers,andstoreenoughapplicationstateinformationtorestoreyourapplicationtoitscurrentstateincaseitisterminatedlater.
//Ifyourapplicationsupportsbackgroundexecution,thismethodiscalledinsteadofapplicationWillTerminate:whentheuserquits.
}
-(void)applicationWillEnterForeground:(UIApplication*)application
{
//Calledaspartofthetransitionfromthebackgroundtotheinactivestate;hereyoucanundomanyofthechangesmadeonenteringthebackground.
}
-(void)applicationDidBecomeActive:(UIApplication*)application
{
//Restartanytasksthatwerepaused(ornotyetstarted)whiletheapplicationwasinactive.IftheapplicationwasprevIoUslyinthebackground,optionallyrefreshtheuserinterface.
}
-(void)applicationWillTerminate:(UIApplication*)application
{
//Calledwhentheapplicationisabouttoterminate.Savedataifappropriate.SeealsoapplicationDidEnterBackground:.
}
@end


MainViewController.m

#import"MainViewController.h"
#import"XMLSAXParser.h"
#import"JSONParser.h"
@interfaceMainViewController()
@end
@implementationMainViewController
-(id)initWithNibName:(NSString*)nibNameOrNilbundle:(NSBundle*)nibBundleOrNil
{
self=[superinitWithNibName:nibNameOrNilbundle:nibBundleOrNil];
if(self){
//Custominitialization
}
returnself;
}
-(void)viewDidLoad
{
[superviewDidLoad];
//Doanyadditionalsetupafterloadingtheview.
self.view.backgroundColor=[UIColorcyanColor];

//XMLSAX解析(逐行解析)
XMLSAXParser*parser=[[XMLSAXParseralloc]init];
[parserstartParse];
NSLog(@"解析后的%@",parser.array);
[parserrelease];
}
-(void)didReceiveMemoryWarning
{
[superdidReceiveMemoryWarning];
//DispoSEOfanyresourcesthatcanberecreated.
}
/*
#pragmamark-Navigation
//Inastoryboard-basedapplication,youwilloftenwanttodoalittlepreparationbeforenavigation
-(void)prepareForSegue:(UIStoryboardSegue*)seguesender:(id)sender
{
//Getthenewviewcontrollerusing[seguedestinationViewController].
//Passtheselectedobjecttothenewviewcontroller.
}
*/
@end


XMLSAXParser.h
#import<Foundation/Foundation.h>
@interfaceXMLSAXParser:NSObject<NSXMLParserDelegate>
@property(nonatomic,retain)NSMutableArray*array;//装学生对象
@property(nonatomic,retain)NSString*tempStr;//临时健在节点内容
-(void)startParse;//开始解析,逐行解析
-(void)startDOMParse;//开始dom解析,按节点解析
@end



XMLSAXParser.m
#import"XMLSAXParser.h"
#import"Student.h"
#import"GdataxMLNode.h"
@implementationXMLSAXParser
//XML解析:逐行解析
-(void)startParse;
{
//XML解析:逐行解析

//从文件列表中读取数据
//1.获取文件路径
NSString*sourcePath=[[NSBundlemainBundle]pathForResource:@"Student"ofType:@"xml"];
//2.通过路径把文件转换成NSData类型
NSData*data=[NSDatadataWithContentsOfFile:sourcePath];

//创建的时候需要给parser一个字符串数据(NSData)
NSXMLParser*parser=[[NSXMLParseralloc]initWithData:data];

//设定代理人
parser.delegate=self;
//开始对文件进行解析
[parserparse];
//内存管理
[parserrelease];

}
-(void)parser:(NSXMLParser*)parserdidStartElement:(NSString*)elementNamenamespaceURI:(NSString*)namespaceURIqualifiedName:(NSString*)qNameattributes:(NSDictionary*)attributeDict
{
//当找到节点头的时候,体统调用这个方法
NSLog(@"节点头");

if([elementNameisEqualToString:@"students"]){
//当找到students节点头的时候,初始化数组
self.array=[NSMutableArrayarray];
}elseif([elementNameisEqualToString:@"student"]){
//当找到student节点时候,创建一个新的学生对象,添加到数组中
Student*stu=[[Studentalloc]init];
[self.arrayaddObject:stu];
[sturelease];

}
}
-(void)parser:(NSXMLParser*)parserfoundCharacters:(NSString*)string
{
//当找到节点内容的时候,调用
NSLog(@"节点内容");
//把内容保存起来,只要碰到节点内容,下一个肯定是节点尾
self.tempStr=string;
}
-(void)parser:(NSXMLParser*)parserdidEndElement:(NSString*)elementNamenamespaceURI:(NSString*)namespaceURIqualifiedName:(NSString*)qName
{
//当找到节点尾时候调用
NSLog(@"节点尾");

//取得之前保存的student对象
Student*stu=[self.arraylastObject];//核心代码,懂了没.........
if([elementNameisEqualToString:@"name"]){
stu.name=self.tempStr;
}elseif([elementNameisEqualToString:@"sex"]){
stu.sex=self.tempStr;
}elseif([elementNameisEqualToString:@"phone"]){
stu.phone=self.tempStr;
}elseif([elementNameisEqualToString:@"number"]){
stu.number=self.tempStr;
}
}
//开始dom解析,按节点解析
-(void)startDOMParse
{
//按节点解析
//1.获取要解析文件文件信息
NSString*xmlPath=[[NSBundlemainBundle]pathForResource:@"Student"ofType:@"xml"];
NSData*data=[NSDatadataWithContentsOfFile:xmlPath];

//参数1:要解析的xml串
//参数2:随便
//参数3:错误信息
GdataxMLDocument*doc=[[GdataxMLDocumentalloc]initWithData:dataoptions:0error:nil];

//2.获取文件的根节点
GdataxMLElement*rootElement=[docrootElement];

//3.进一步搜索所有的子节点
//返回一个装满了student节点(GdataxMLElement对象)的数组
NSArray*array=[rootElementelementsForName:@"student"];

self.array=[NSMutableArrayarray];
//4.遍历数组,把student节点的每个子节点取出来
for(GdataxMLElement*elementinarray){

Student*stu=[[Studentalloc]init];

GdataxMLElement*nameElement=[[elementelementsForName:@"name"]lastObject];

//从name节点中取值
NSString*name=[nameElementstringValue];

//给学生对象的属性赋值
stu.name=name;

//把学生对象添加到数组中-----------其他的雷同
[self.arrayaddObject:stu];
[sturelease];
}
}
@end

Student.h

#import<Foundation/Foundation.h>
@interfaceStudent:NSObject
@property(nonatomic,retain)NSString*number;
@property(nonatomic,retain)NSString*name;
@property(nonatomic,retain)NSString*sex;
@property(nonatomic,copy)NSString*phone;
@end

Student.m

#import"Student.h"
@implementationStudent
-(void)dealloc
{
[_namerelease];
[_numberrelease];
[_sexrelease];
[_phonerelease];
[superdealloc];
}
//当这个类的对象被NSLog输出时候,系统会先调用这个方法,如果这个方法被重写,就直接输出重写的内容,否则就输出系统默认的内容
-(NSString*)description
{
return[NSStringstringWithFormat:@"name:%@sex:%@phone:%@number:%@",self.name,self.sex,self.phone,self.number];
}
@end


这里需要注意的是添加第三方类的步骤:

直接添加第三方类是有错的

GdataxMLNode.h

// libxml includes require that the target Header Search Paths contain

//

// /usr/include/libxml2

// and Other Linker Flags contain

// -lxml2

在下面的对上面的文件中首先搜索Header Search 然后在第二行中添加/usr/include/libxml2

然后同理搜索Other Linker-lxml2

这样第三方类就可以使用了 .



XML在不同的语言里解析方式都是一样的,只不过实现的语法不同而已。基本的解析方式有两种,一种叫SAX,另一种叫DOM。SAX是基于事件流的解析,DOM是基于XML文档树结构的解析.假设我们XML的内容和结构如下:


[xhtml]view plaincopy

<?xmlversion="1.0"encoding="UTF-8"?>
<employees>
<employee>
<name>ddviplinux</name>
<sex>m</sex>
<age>30</age>
</employee>
</employees>

下面是解析XMl常用的Dom和Sex方法

1.DOM生成和解析XML文档

为 XML 文档的已解析版本定义了一组接口。解析器读入整个文档,然后构建一个驻留内存的树结构,然后代码就可以使用 DOM 接口来操作这个树结构。优点:整个文档树在内存中,便于操作;支持删除修改、重新排列等多种功能;缺点:将整个文档调入内存(包括无用的节点),浪费时间和空间;使用场合:一旦解析了文档还需多次访问这些数据;硬件资源充足(内存、cpu)。


[java]copy

publicvoidparserXml(StringfileName){
try{
DocumentBuilderFactorydbf=DocumentBuilderFactory.newInstance();
DocumentBuilderdb=dbf.newDocumentBuilder();
Documentdocument=db.parse(fileName);
NodeListemployees=document.getChildNodes();
for(inti=0;i<employees.getLength();i++){
Nodeemployee=employees.item(i);
NodeListemployeeInfo=employee.getChildNodes();
for(intj=0;j<employeeInfo.getLength();j++){
Nodenode=employeeInfo.item(j);
NodeListemployeeMeta=node.getChildNodes();
for(intk=0;k<employeeMeta.getLength();k++){
System.out.println(employeeMeta.item(k).getNodeName()+":"+employeeMeta.item(k).getTextContent());
}
}
}
System.out.println("解析完毕");
}catch(Exceptione){
System.out.println(e.getMessage());
}
}


2.SAX生成和解析XML文档

解决DOM的问题,出现了SAX。SAX ,事件驱动。当解析器发现元素开始、元素结束、文本、文档的开始或结束等时,发送事件,程序员编写响应这些事件的代码,保存数据。优点:不用事先调入整个文档,占用资源少;SAX解析器代码比DOM解析器代码小,适于Applet,下载。缺点:不是持久的;事件过后,若没保存数据,那么数据就丢了;无状态性;从事件中只能得到文本,但不知该文本属于哪个元素;使用场合:Applet;只需XML文档的少量内容,很少回头访问;机器内存少;

copy

publicvoidparserXml(StringfileName){
SAXParserFactorysaxfac=SAXParserFactory.newInstance();
try{
SAXParsersaxparser=saxfac.newSAXParser();
InputStreamis=newFileInputStream(fileName);
saxparser.parse(is,newMySAXHandler());
}catch(Exceptione){
e.printStackTrace();
}
}

猜你在找的XML相关文章