XML文件的解析方式有两种:
iOS提供了两套解析XML文件的框架:NSXMLParser和libxml2
iOS中通常使用这两种框架来解析XML文件:一种是使用iOS自带的NSXMLParser框架进行SAX解析;另一种是使用Google开发的GDataXMLNode第三方框架进行DOM方式解析,它对libxml2框架进行了OC的封装。
DOM解析方式:一次性将XML文件解析完毕加载进内存,比较适合解析小文件
以下为本例要解析的XML文件内容:
<?xml version="1.0" encoding="UTF-8"?>
<students>
<student>
<name>Lotheve</name>
<age>21</age>
<sex>male</sex>
</student>
<student>
<name>BB</name>
<age>20</age>
<sex>Female</sex>
</student>
</students>
相应的model文件则包含了name、age、sex3个属性:
@interface StudentModel : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *age;
@property (nonatomic, strong) NSString *sex;
@end
首先导入GDataXMLNode文件,可以从pod安装,也可以手动添加相关文件到工程。这里直接从master中copy了GDataXMLNode文件到工程。
导入libxml2动态库 targets–Build Phases–link Binary With Libraries
或者也可以不导入动态库,选择设置链接参数(自动链接libxml2库)
在Other Linker Flags中加入-lxml2 (二者选其一即可)
然后要做的是设置libxml2的头文件搜索路径(为了能找到libxml2库的所有头文件),在Head Search Path中加入/usr/include/libxml2
OK!编译程序,为报错则环境配置成功。
接下来便可在源文件中引用GDataXMLNode.h进行XML的解析工作了。改接口文件主要涉及3个类:
@interface DOMViewController ()
@property (nonatomic, strong) NSMutableArray *arrayStudents; //存储对象数据的数组
@end
@implementation DOMViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self mainOperation];
}
- (void)mainOperation{
self.arrayStudents = [NSMutableArray arrayWithCapacity:0];
NSError *error= nil;
//解析xml文件,解析完成后实例化GDataXMLDocument对象
GDataXMLDocument *document = [[GDataXMLDocument alloc]initWithData:[NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"student" ofType:@"xml"]] error:&error];
if (error) {
NSLog(@"%@",error.localizedDescription);
return;
}
//先获取根元素,再获取所有的student元素
GDataXMLElement *rootElement = [document rootElement];
NSArray *array = [rootElement elementsForName:@"student"];
//从每个student元素中获取子元素的文本数据并映射到模型对象
for (GDataXMLElement *studentElement in array) {
StudentModel *model = [[StudentModel alloc]init];
[model setValue:[[[studentElement elementsForName:@"name"] firstObject] stringValue] forKey:@"name"];
[model setValue:[[[studentElement elementsForName:@"age"] firstObject] stringValue] forKey:@"age"];
[model setValue:[[[studentElement elementsForName:@"sex"] firstObject] stringValue] forKey:@"sex"];
[self.arrayStudents addObject:model];
}
for (StudentModel *model in self.arrayStudents) {
NSLog(@"name:%@, age:%@, sex:%@",model.name,model.age,model.sex);
}
}
打印结果如下:
SAX解析方式: 从根元素开始,从上到下依次往下解析,比较适合解析大文件。
NSXMLParser是iOS SDK中自带的框架,无需导入任何外部文件,直接使用。
#import "DOMViewController.h"
#import "StudentModel.h"
#import "GDataXMLNode.h"
@interface DOMViewController ()
@property (nonatomic, strong) NSMutableArray *arrayStudents; //存储对象数据的数组
@end
@implementation DOMViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self mainOperation];
}
- (void)mainOperation{
self.arrayStudents = [NSMutableArray arrayWithCapacity:0];
NSError *error= nil;
//解析xml文件,解析完成后实例化GDataXMLDocument对象
GDataXMLDocument *document = [[GDataXMLDocument alloc]initWithData:[NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"student" ofType:@"xml"]] error:&error];
if (error) {
NSLog(@"%@",error.localizedDescription);
return;
}
//先获取根元素,再获取所有的student元素
GDataXMLElement *rootElement = [document rootElement];
NSArray *array = [rootElement elementsForName:@"student"];
//从每个student元素中获取子元素的文本数据并映射到模型对象
for (GDataXMLElement *studentElement in array) {
StudentModel *model = [[StudentModel alloc]init];
[model setValue:[[[studentElement elementsForName:@"name"] firstObject] stringValue] forKey:@"name"];
[model setValue:[[[studentElement elementsForName:@"age"] firstObject] stringValue] forKey:@"age"];
[model setValue:[[[studentElement elementsForName:@"sex"] firstObject] stringValue] forKey:@"sex"];
[self.arrayStudents addObject:model];
/*! * 注意 * 此处是从元素文本取值,若从元素属性取值,应该用下面的方法 * [[元素对象 attributeForName:@"属性名"] stringValue]; */
}
for (StudentModel *model in self.arrayStudents) {
NSLog(@"name:%@, age:%@, sex:%@",model.name,model.age,model.sex);
}
}
@end
打印结果如下:
可以看到以上两种方式成功解析了该XML文件。