IOS解析XML文档

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: 小  |  中  |  大  |  超大  

前段时间想找点事做,就是试着看能不能用豆瓣的API做点什么,于是就碰到了这个问题——xml解析。

老师还没讲,只能自己去查。

XML文档解析主要有SAX和DOM两种模式,IOS上两种模式都可以用,这里就不做过多介绍,我选择的SAX模式。

IOS解析XML用的是自带的NSXML框架,框架的核心是NSXMLParser类和它的委托协议NSXMLParserDelegate,其主要的解析工作是在NSXMLParserDelegate实现类中完成的。委托中定义了许多回掉方法,在SAX解析器从上到下遍历XML文档的过程中,遇到开始标签、结束标签、文档开始、文档结束和字符串结束是就会触发这些方法。这些方法有很多,下面我们列出5个常用的方法。

在文档开始时触发

-(void)parserDidStartDocument:(NSXMLParser *)parser

遇到一个新标签是触发,其中namespaceURI是命名空间,qualifiedName是限定名,attributes是字典类型的属性集合。

-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict

找到字符串时触发

-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string

遇到结束标签时触发

-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName

在文档结束时触发

-(void)parserDidEndDocument:(NSXMLParser *)parser

下面通过一个具体的例子来看整个的调用与解析过程

首先这是我们将要解析的XML文件 "info.xml"

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

​ ​ ​ ​<personid="1">​ ​ ​ ​ ​<firstName>Wythe</firstName>​ ​ ​ ​ ​

​ ​ ​ ​ ​<lastName>xu</lastName>​ ​ ​ ​ ​

​ ​ ​ ​ ​<age>22</age>​ ​ ​ ​

​ ​ ​ ​</person>​ ​ ​

​ ​ ​ ​<personid="2">​ ​ ​ ​

​ ​ ​ ​ ​<firstName>li</firstName>​ ​ ​ ​ ​

​ ​ ​ ​ ​<lastName>si</lastName>​ ​ ​ ​ ​

​ ​ ​ ​ ​<age>31</age>​ ​ ​ ​

​ ​ ​ ​</person>​ ​ ​ ​

​ ​ ​ ​ ​<personid="3">​ ​ ​ ​ ​

​ ​ ​ ​ ​<firstName>Dipen</firstName>​ ​ ​ ​ ​

​ ​ ​ ​ ​<lastName>Shah</lastName>​ ​ ​ ​ ​

​ ​ ​ ​ ​<age>24</age>​ ​ ​ ​

​ ​ ​ ​</person>​ ​ ​ ​

​ ​ ​</root>

接来来是一个头文件 "ViewController.h"

#import<UIKit/UIKit.h>@interfaceViewController : UIViewController<NSXMLParserDelegate>@PRoperty NSXMLParser*parser;

@property NSMutableArray*person;

@property NSString*currenttag;@end

然后是它的实现文件 "ViewController.m"

#import"ViewController.h"@interfaceViewController ()@end@implementationViewController@synthesizeparser = _parser , person = _person , currenttag =_currenttag;- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

{

self=[super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];if(self) {//Custom initialization}returnself;

}- (void)viewDidLoad

{

[super viewDidLoad];

NSString*xmlFilePath = [[NSBundle mainBundle]pathForResource:@"info"ofType:@"xml"];

NSData*data =[[NSData alloc]initWithContentsOfFile:xmlFilePath];

self.parser=[[NSXMLParser alloc]initWithData:data];

self.parser.delegate=self;

[self.parser parse];

NSLog(@"%@",_person);

}- (void)didReceiveMemoryWarning

{

[super didReceiveMemoryWarning];//Dispose of any resources that can be recreated.}#pragmamark delegate method

-(void)parserDidStartDocument:(NSXMLParser *)parser

{

_person=[[NSMutableArray alloc]init];

NSLog(@"start parse 1");

}-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict

{

_currenttag=elementName;if([_currenttag isEqualToString:@"person"]) {

NSString*_id = [attributeDict objectForKey:@"id"];

NSMutableDictionary*dict =[[NSMutableDictionary alloc]init];

[dict setObject:_id forKey:@"id"];

[_person addObject:dict];

}

NSLog(@"start element");

}-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{

NSMutableDictionary*dict =[_person lastObject];if([_currenttag isEqualToString:@"firstName"] &&dict) {

[dict setObject:stringforKey:@"firstName"];

}if([_currenttag isEqualToString:@"lastName"] &&dict) {

[dict setObject:stringforKey:@"lastName"];

}if([_currenttag isEqualToString:@"age"] &&dict) {

[dict setObject:stringforKey:@"age"];

}

NSLog(@"found characters");

}-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName

{

_currenttag=nil;

NSLog(@"end element");

}-(void)parserDidEndDocument:(NSXMLParser *)parser

{

NSLog(@"parse end");

}@end

通过断电和输出信息,我们可以知道整个解析过程是 开始解析文档、开始标签、找到字符串、结束标签、文档结束。

2014-09-1016:45:32.920xmlforblog[3820:60b] start parse12014-09-1016:45:32.921xmlforblog[3820:60b] start element2014-09-1016:45:32.922xmlforblog[3820:60b] found characters2014-09-1016:45:32.922xmlforblog[3820:60b] start element2014-09-1016:45:32.922xmlforblog[3820:60b] found characters2014-09-1016:45:32.922xmlforblog[3820:60b] start element2014-09-1016:45:32.923xmlforblog[3820:60b] found characters2014-09-1016:45:32.923xmlforblog[3820:60b] end element2014-09-1016:45:32.923xmlforblog[3820:60b] found characters2014-09-1016:45:32.923xmlforblog[3820:60b] start element2014-09-1016:45:32.924xmlforblog[3820:60b] found characters2014-09-1016:45:32.924xmlforblog[3820:60b] end element2014-09-1016:45:32.924xmlforblog[3820:60b] found characters2014-09-1016:45:32.924xmlforblog[3820:60b] start element2014-09-1016:45:32.925xmlforblog[3820:60b] found characters2014-09-1016:45:32.925xmlforblog[3820:60b] end element2014-09-1016:45:32.925xmlforblog[3820:60b] found characters2014-09-1016:45:32.925xmlforblog[3820:60b] end element2014-09-1016:45:32.926xmlforblog[3820:60b] found characters2014-09-1016:45:32.926xmlforblog[3820:60b] start element2014-09-1016:45:32.928xmlforblog[3820:60b] found characters2014-09-1016:45:32.929xmlforblog[3820:60b] start element2014-09-1016:45:32.929xmlforblog[3820:60b] found characters2014-09-1016:45:32.929xmlforblog[3820:60b] end element2014-09-1016:45:32.930xmlforblog[3820:60b] found characters2014-09-1016:45:32.930xmlforblog[3820:60b] start element2014-09-1016:45:32.930xmlforblog[3820:60b] found characters2014-09-1016:45:32.930xmlforblog[3820:60b] end element2014-09-1016:45:32.931xmlforblog[3820:60b] found characters2014-09-1016:45:32.931xmlforblog[3820:60b] start element2014-09-1016:45:32.931xmlforblog[3820:60b] found characters2014-09-1016:45:32.931xmlforblog[3820:60b] end element2014-09-1016:45:32.931xmlforblog[3820:60b] found characters2014-09-1016:45:32.932xmlforblog[3820:60b] end element2014-09-1016:45:32.932xmlforblog[3820:60b] found characters2014-09-1016:45:32.932xmlforblog[3820:60b] start element2014-09-1016:45:32.932xmlforblog[3820:60b] found characters2014-09-1016:45:32.933xmlforblog[3820:60b] start element2014-09-1016:45:32.933xmlforblog[3820:60b] found characters2014-09-1016:45:32.933xmlforblog[3820:60b] end element2014-09-1016:45:32.933xmlforblog[3820:60b] found characters2014-09-1016:45:32.934xmlforblog[3820:60b] start element2014-09-1016:45:32.934xmlforblog[3820:60b] found characters2014-09-1016:45:32.934xmlforblog[3820:60b] end element2014-09-1016:45:32.934xmlforblog[3820:60b] found characters2014-09-1016:45:32.935xmlforblog[3820:60b] start element2014-09-1016:45:32.935xmlforblog[3820:60b] found characters2014-09-1016:45:32.935xmlforblog[3820:60b] end element2014-09-1016:45:32.935xmlforblog[3820:60b] found characters2014-09-1016:45:32.936xmlforblog[3820:60b] end element2014-09-1016:45:32.936xmlforblog[3820:60b] found characters2014-09-1016:45:32.936xmlforblog[3820:60b] end element2014-09-1016:45:32.936xmlforblog[3820:60b] parse end2014-09-1016:45:32.936xmlforblog[3820:60b] (

{

age=22;

firstName=Wythe;id=1;

lastName=xu;

},

{

age=31;

firstName=li;id=2;

lastName=si;

},

{

age=24;

firstName=Dipen;id=3;

lastName=Shah;

}

)

执行结果

而我们的处理主要是在 开始标签、找到字符串 (

-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict

-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string

)中。

遇到开始标签时,我们现判断标签,名字,如果是person,表明接下来就是person的信息,这样我们就先创建一个可变字典,以便将来存放它的值。

-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict

{

_currenttag=elementName;if([_currenttag isEqualToString:@"person"]) {

NSString*_id = [attributeDict objectForKey:@"id"];

NSMutableDictionary*dict =[[NSMutableDictionary alloc]init];

[dict setObject:_id forKey:@"id"];

[_person addObject:dict];

}

NSLog(@"start element");

}

在找到字符串时,我们就是通过判断当前标签名,将对应的信息保存到刚刚创建的字典中

-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{

NSMutableDictionary*dict =[_person lastObject];if([_currenttag isEqualToString:@"firstName"] &&dict) {

[dict setObject:stringforKey:@"firstName"];

}if([_currenttag isEqualToString:@"lastName"] &&dict) {

[dict setObject:stringforKey:@"lastName"];

}if([_currenttag isEqualToString:@"age"] &&dict) {

[dict setObject:stringforKey:@"age"];

}

NSLog(@"found characters");

}

不断循环这样的过程,最后我们就可以解析出整个XML文档。

另外说一句,这只是解析一般的文档,如果你跟我曾经一样学会这个就去解析豆瓣API的XML文档,会发现行不通。这时因为许多网站因为它的数据较多,为了避免标签的重复,使用了命名空间,带有命名空间的XML文档解析和这稍有不同。

以后我会写带命名空间的XML文档解析,敬请期待。

拖了快一个月了,今天终于写完。以后不能这么懒了

​

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航