一、实现NSXMLParserDelegate代理接口,创建解析器,调用开始方法启动解析:
#import "ViewController.h"
//实现NSXMLParserDelegate,处理xml解析时触发的各个方法
@interface ViewController () <NSXMLParserDelegate>
//存储xml解析结果列表
@property (nonatomic, strong) NSMutableArray *infoList;
//暂时存储节点内容
@property (nonatomic, strong) NSMutableString *elementContent;
@end
@implementation ViewController
/*
懒加载初始化列表
*/
- (NSMutableArray *)infoList{
if(_infoList == nil){
_infoList = [NSMutableArray array];
}
return _infoList;
}
- (void)viewDidLoad {
[super viewDidLoad];
/*
xml文档示例:
<UserInfos>
<UserInfo uId="1">
<name>姓名1</name>
<job>IT</job>
</UserInfo>
<UserInfo uId="2">
<name>姓名2</name>
<job>IT</job>
</UserInfo>
</UserInfos>
*/
NSString *xmlStr = @"<UserInfos><UserInfo uId=\"1\"><name>姓名1</name><job>IT</job></UserInfo><UserInfo uId=\"2\"><name>姓名2</name><job>IT</job></UserInfo></UserInfos>";
NSData *data =[xmlStr dataUsingEncoding:NSUTF8StringEncoding];
[self parseXml:data];
}
/*
0.实现NSXMLParserDelegate,创建解析器,开始解析xml
*/
- (void) parseXml:(NSData *)data{
//传入xml字符串的data对象,创建xml解析器
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
//设置代理实现,监听解析方法
parser.delegate = self;
//开始解析
[parser parse];
}
@end
二、监听各个解析方法,取出节点与节点内容并存储:
各方法执行顺序:
1.parserDidStartDocument:开始解析xml时触发
2.didStartElement:读取xml节点开始位置时触发,如<节点名称>节点内容</节点名称>前面部分
3.foundCharacters:读取xml节点文本内容时触发,如<节点名称>节点内容</节点名称>中间内容部分
4.didEndElement:读取xml节点结束位置时触发,如<节点名称>节点内容</节点名称>后面部分
5.parserDidEndDocument:结束解析xml时触发
/*
1.开始解析xml时触发
*/
- (void)parserDidStartDocument:(NSXMLParser *)parser{
NSLog(@"开始解析");
//初始化存储列表
self.infoList = [NSMutableArray array];
}
/*
2.读取xml节点开始位置时触发,如<节点名称>节点内容</节点名称>前面部分
*/
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(nullable NSString *)namespaceURI qualifiedName:(nullable NSString *)qName attributes:(NSDictionary<NSString *, NSString *> *)attributeDict{
NSLog(@"startElement 节点名称: %@", elementName);
//获取节点名称,进行比对
if([elementName isEqualToString:@"UserInfo"]){
//初始化对象
UserInfo *info = [[UserInfo alloc] init];
//获取节点属性的值并赋值
info.uId = attributeDict[@"uId"];
//将单个对象存入列表中
[self.infoList addObject:info];
}
//用于存储节点内容,节点开始时重置为空串
[self.elementContent setString:@""];
}
/*
3.读取xml节点文本内容时触发,如<节点名称>节点内容</节点名称>中间内容部分
*/
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
NSLog(@"foundCharacters 节点内容: %@", string);
//存储节点内容
[self.elementContent appendString:string];
}
/*
4.读取xml节点结束位置时触发,如<节点名称>节点内容</节点名称>后面部分
*/
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(nullable NSString *)namespaceURI qualifiedName:(nullable NSString *)qName{
NSLog(@"endElement 节点名称: %@", elementName);
//从列表中获取最后一个对象引用
UserInfo *info = [self.infoList lastObject];
//在节点结束时,将节点内容赋值
if([elementName isEqualToString:@"name"]){
info.name = self.elementContent;
} else if([elementName isEqualToString:@"job"]){
info.job = self.elementContent;
}
}
/*
5.结束解析xml时触发
*/
- (void)parserDidEndDocument:(NSXMLParser *)parser{
//此时所有数据已解析完存入列表
NSLog(@"结束解析 list: %@", self.infoList);
}