进行XML的解析时,用到SAX工具进行XML解析(代理的回调机制)
NSXMLParser类,是系统自带的xml解析工具,采用SAX方式解析数据
解析过程由NSXMLParserDelegate代理回调实现
首先创建xml文件(Students.xml):
<?xml version="1.0" encoding="UTF-8" ?>
<students>
<student type="CEO">
<name>zhangsan001</name>
<age>18</age>
<gender>man</gender>
</student>
<student>
<name>zhangsan002</name>
<age>10</age>
<gender>woman</gender>
</student>
<student>
<name>zhangsan003</name>
<age>12</age>
<gender>manman</gender>
</student>
</students>
解析过程:开始解析文档-> 开始解析标签->取值->结束解析标签->开始解析标签->取值->结束解析标签......->结束解析文档
可以看出“开始解析文档”和“结束解析文档”两个代理方法在解析过程中只执行了一次,“开始解析标签”、“取值”、“结束解析标签”循环执行
在代码中创建NSXMLParser对象,并读取NSData数据,设置代理,开始解析
看代码:
// 通过NSBundle获取xml文件的路径
NSString *path = [[NSBundle mainBundle] pathForResource:@"Students" ofType:@"xml"];
// 通过路径,读取成NSData数据
NSData *data = [[NSData alloc] initWithContentsOfFile:path];
NSLog(@"%@", data);
// 创建解析对象
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
// 设置代理
parser.delegate = self;
// 开始解析
[parser parse];
这里先创建三个私有属性,作用在后面说明
@property (nonatomic, retain) NSMutableArray *allDataArray;
@property (nonatomic, copy) NSMutableString *element;
@property (nonatomic, retain) Student *student;
实现“开始解析文档”和“结束解析文档”的代理方法:
#pragma mark - 开始解析文档
- (void)parserDidStartDocument:(NSXMLParser *)parser
{
// 初始化数组
_allDataArray = [NSMutableArray array];
// 初始化可变字符串
_element = [NSMutableString string];
}
#pragma mark - 结束解析文档
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
NSLog(@"%@", _allDataArray);
}
“开始解析标签”、“取值”、“结束解析标签”的代理方法:
#pragma mark - 开始解析标签
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
// 判断标签 == student的场合
if ([elementName isEqualToString:@"student"]) {
// 初始化student对象
_student = [Student new];
// 取得属性
if (attributeDict[@"type"]) {
NSLog(@"type = %@", attributeDict[@"type"]);
}
}
}
#pragma mark - 取值
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
// 将前一次的值清空
[_element setString:@""];
// 将本次值赋给_element
[_element appendString:string];
}
#pragma mark - 结束解析标签
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
// 判断标签是否是student对象的属性标签
if (![elementName isEqualToString:@"student"] && ![elementName isEqualToString:@"students"]) {
// 给student属性赋值
[_student setValue:_element forKey:elementName];
} else if ([elementName isEqualToString:@"student"]) { // 判断结束标签 == student的场合
// 将student添加到数组中
[_allDataArray addObject:_student];
}
}
看看执行结果吧:
2015-06-23 11:46:55.738 Lesson_15_xml[2398:101202] type = CEO
2015-06-23 11:46:55.738 Lesson_15_xml[2398:101202] (
"name = zhangsan001 age = 18 gender = man",
"name = zhangsan002 age = 10 gender = woman",
"name = zhangsan003 age = 12 gender = manman"
)
这样就可以了。