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

  1. AppDelegate.m
  2. #import"AppDelegate.h"
  3. #import"MainViewController.h"
  4. @implementationAppDelegate
  5. -(BOOL)application:(UIApplication*)applicationdidFinishLaunchingWithOptions:(NSDictionary*)launchOptions
  6. {
  7. self.window=[[UIWindowalloc]initWithFrame:[[UIScreenmainScreen]bounds]];
  8. //Overridepointforcustomizationafterapplicationlaunch.
  9. self.window.backgroundColor=[UIColorwhiteColor];
  10. [self.windowmakeKeyAndVisible];
  11.  
  12.  
  13. MainViewController*mainVC=[[MainViewControlleralloc]init];
  14. UINavigationController*naviVC=[[UINavigationControlleralloc]initWithRootViewController:mainVC];
  15. self.window.rootViewController=naviVC;
  16. [naviVCrelease];
  17. [mainVCrelease];
  18.  
  19. [_windowrelease];
  20. returnYES;
  21. }
  22. -(void)dealloc
  23. {
  24. [_windowrelease];
  25. [superdealloc];
  26. }
  27. -(void)applicationWillResignActive:(UIApplication*)application
  28. {
  29. //Sentwhentheapplicationisabouttomovefromactivetoinactivestate.Thiscanoccurforcertaintypesoftemporaryinterruptions(suchasanincomingphonecallorSMSmessage)orwhentheuserquitstheapplicationanditbeginsthetransitiontothebackgroundstate.
  30. //UsethismethodtopauSEOngoingtasks,disabletimers,andthrottledownOpenGLESframerates.Gamesshouldusethismethodtopausethegame.
  31. }
  32. -(void)applicationDidEnterBackground:(UIApplication*)application
  33. {
  34. //Usethismethodtoreleasesharedresources,saveuserdata,invalidatetimers,andstoreenoughapplicationstateinformationtorestoreyourapplicationtoitscurrentstateincaseitisterminatedlater.
  35. //Ifyourapplicationsupportsbackgroundexecution,thismethodiscalledinsteadofapplicationWillTerminate:whentheuserquits.
  36. }
  37. -(void)applicationWillEnterForeground:(UIApplication*)application
  38. {
  39. //Calledaspartofthetransitionfromthebackgroundtotheinactivestate;hereyoucanundomanyofthechangesmadeonenteringthebackground.
  40. }
  41. -(void)applicationDidBecomeActive:(UIApplication*)application
  42. {
  43. //Restartanytasksthatwerepaused(ornotyetstarted)whiletheapplicationwasinactive.IftheapplicationwasprevIoUslyinthebackground,optionallyrefreshtheuserinterface.
  44. }
  45. -(void)applicationWillTerminate:(UIApplication*)application
  46. {
  47. //Calledwhentheapplicationisabouttoterminate.Savedataifappropriate.SeealsoapplicationDidEnterBackground:.
  48. }
  49. @end


  1. MainViewController.m
  2.  
  3. #import"MainViewController.h"
  4. #import"XMLSAXParser.h"
  5. #import"JSONParser.h"
  6. @interfaceMainViewController()
  7. @end
  8. @implementationMainViewController
  9. -(id)initWithNibName:(NSString*)nibNameOrNilbundle:(NSBundle*)nibBundleOrNil
  10. {
  11. self=[superinitWithNibName:nibNameOrNilbundle:nibBundleOrNil];
  12. if(self){
  13. //Custominitialization
  14. }
  15. returnself;
  16. }
  17. -(void)viewDidLoad
  18. {
  19. [superviewDidLoad];
  20. //Doanyadditionalsetupafterloadingtheview.
  21. self.view.backgroundColor=[UIColorcyanColor];
  22.  
  23. //XMLSAX解析(逐行解析)
  24. XMLSAXParser*parser=[[XMLSAXParseralloc]init];
  25. [parserstartParse];
  26. NSLog(@"解析后的%@",parser.array);
  27. [parserrelease];
  28. }
  29. -(void)didReceiveMemoryWarning
  30. {
  31. [superdidReceiveMemoryWarning];
  32. //DispoSEOfanyresourcesthatcanberecreated.
  33. }
  34. /*
  35. #pragmamark-Navigation
  36. //Inastoryboard-basedapplication,youwilloftenwanttodoalittlepreparationbeforenavigation
  37. -(void)prepareForSegue:(UIStoryboardSegue*)seguesender:(id)sender
  38. {
  39. //Getthenewviewcontrollerusing[seguedestinationViewController].
  40. //Passtheselectedobjecttothenewviewcontroller.
  41. }
  42. */
  43. @end


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



  1. XMLSAXParser.m
  2. #import"XMLSAXParser.h"
  3. #import"Student.h"
  4. #import"GdataxMLNode.h"
  5. @implementationXMLSAXParser
  6. //XML解析:逐行解析
  7. -(void)startParse;
  8. {
  9. //XML解析:逐行解析
  10.  
  11. //从文件列表中读取数据
  12. //1.获取文件路径
  13. NSString*sourcePath=[[NSBundlemainBundle]pathForResource:@"Student"ofType:@"xml"];
  14. //2.通过路径把文件转换成NSData类型
  15. NSData*data=[NSDatadataWithContentsOfFile:sourcePath];
  16.  
  17. //创建的时候需要给parser一个字符串数据(NSData)
  18. NSXMLParser*parser=[[NSXMLParseralloc]initWithData:data];
  19.  
  20. //设定代理人
  21. parser.delegate=self;
  22. //开始对文件进行解析
  23. [parserparse];
  24. //内存管理
  25. [parserrelease];
  26.  
  27. }
  28. -(void)parser:(NSXMLParser*)parserdidStartElement:(NSString*)elementNamenamespaceURI:(NSString*)namespaceURIqualifiedName:(NSString*)qNameattributes:(NSDictionary*)attributeDict
  29. {
  30. //当找到节点头的时候,体统调用这个方法
  31. NSLog(@"节点头");
  32.  
  33. if([elementNameisEqualToString:@"students"]){
  34. //当找到students节点头的时候,初始化数组
  35. self.array=[NSMutableArrayarray];
  36. }elseif([elementNameisEqualToString:@"student"]){
  37. //当找到student节点时候,创建一个新的学生对象,添加到数组中
  38. Student*stu=[[Studentalloc]init];
  39. [self.arrayaddObject:stu];
  40. [sturelease];
  41.  
  42. }
  43. }
  44. -(void)parser:(NSXMLParser*)parserfoundCharacters:(NSString*)string
  45. {
  46. //当找到节点内容的时候,调用
  47. NSLog(@"节点内容");
  48. //把内容保存起来,只要碰到节点内容,下一个肯定是节点尾
  49. self.tempStr=string;
  50. }
  51. -(void)parser:(NSXMLParser*)parserdidEndElement:(NSString*)elementNamenamespaceURI:(NSString*)namespaceURIqualifiedName:(NSString*)qName
  52. {
  53. //当找到节点尾时候调用
  54. NSLog(@"节点尾");
  55.  
  56. //取得之前保存的student对象
  57. Student*stu=[self.arraylastObject];//核心代码,懂了没.........
  58. if([elementNameisEqualToString:@"name"]){
  59. stu.name=self.tempStr;
  60. }elseif([elementNameisEqualToString:@"sex"]){
  61. stu.sex=self.tempStr;
  62. }elseif([elementNameisEqualToString:@"phone"]){
  63. stu.phone=self.tempStr;
  64. }elseif([elementNameisEqualToString:@"number"]){
  65. stu.number=self.tempStr;
  66. }
  67. }
  68. //开始dom解析,按节点解析
  69. -(void)startDOMParse
  70. {
  71. //按节点解析
  72. //1.获取要解析文件文件信息
  73. NSString*xmlPath=[[NSBundlemainBundle]pathForResource:@"Student"ofType:@"xml"];
  74. NSData*data=[NSDatadataWithContentsOfFile:xmlPath];
  75.  
  76. //参数1:要解析的xml串
  77. //参数2:随便
  78. //参数3:错误信息
  79. GdataxMLDocument*doc=[[GdataxMLDocumentalloc]initWithData:dataoptions:0error:nil];
  80.  
  81. //2.获取文件的根节点
  82. GdataxMLElement*rootElement=[docrootElement];
  83.  
  84. //3.进一步搜索所有的子节点
  85. //返回一个装满了student节点(GdataxMLElement对象)的数组
  86. NSArray*array=[rootElementelementsForName:@"student"];
  87.  
  88. self.array=[NSMutableArrayarray];
  89. //4.遍历数组,把student节点的每个子节点取出来
  90. for(GdataxMLElement*elementinarray){
  91.  
  92. Student*stu=[[Studentalloc]init];
  93.  
  94. GdataxMLElement*nameElement=[[elementelementsForName:@"name"]lastObject];
  95.  
  96. //从name节点中取值
  97. NSString*name=[nameElementstringValue];
  98.  
  99. //给学生对象的属性赋值
  100. stu.name=name;
  101.  
  102. //把学生对象添加到数组中-----------其他的雷同
  103. [self.arrayaddObject:stu];
  104. [sturelease];
  105. }
  106. }
  107. @end

  1. Student.h
  2.  
  3. #import<Foundation/Foundation.h>
  4. @interfaceStudent:NSObject
  5. @property(nonatomic,retain)NSString*number;
  6. @property(nonatomic,retain)NSString*name;
  7. @property(nonatomic,retain)NSString*sex;
  8. @property(nonatomic,copy)NSString*phone;
  9. @end

Student.m

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


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

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

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

  1. <?xmlversion="1.0"encoding="UTF-8"?>
  2. <employees>
  3. <employee>
  4. <name>ddviplinux</name>
  5. <sex>m</sex>
  6. <age>30</age>
  7. </employee>
  8. </employees>

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

1.DOM生成和解析XML文档

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


[java]copy

  1. publicvoidparserXml(StringfileName){
  2. try{
  3. DocumentBuilderFactorydbf=DocumentBuilderFactory.newInstance();
  4. DocumentBuilderdb=dbf.newDocumentBuilder();
  5. Documentdocument=db.parse(fileName);
  6. NodeListemployees=document.getChildNodes();
  7. for(inti=0;i<employees.getLength();i++){
  8. Nodeemployee=employees.item(i);
  9. NodeListemployeeInfo=employee.getChildNodes();
  10. for(intj=0;j<employeeInfo.getLength();j++){
  11. Nodenode=employeeInfo.item(j);
  12. NodeListemployeeMeta=node.getChildNodes();
  13. for(intk=0;k<employeeMeta.getLength();k++){
  14. System.out.println(employeeMeta.item(k).getNodeName()+":"+employeeMeta.item(k).getTextContent());
  15. }
  16. }
  17. }
  18. System.out.println("解析完毕");
  19. }catch(Exceptione){
  20. System.out.println(e.getMessage());
  21. }
  22. }


2.SAX生成和解析XML文档

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

copy

  1. publicvoidparserXml(StringfileName){
  2. SAXParserFactorysaxfac=SAXParserFactory.newInstance();
  3. try{
  4. SAXParsersaxparser=saxfac.newSAXParser();
  5. InputStreamis=newFileInputStream(fileName);
  6. saxparser.parse(is,newMySAXHandler());
  7. }catch(Exceptione){
  8. e.printStackTrace();
  9. }
  10. }

猜你在找的XML相关文章