iOS-XML文档解析(NSXMLParser)

这次我们使用iOS SDK中的NSXMLParser类来进行XML文档的解析。这个用于解析XML文档(包含DTD声明)的类是基于数据驱动的方式实现的。当它在处理XML文档过程中遇到相关节点(元素,属性,CDATA块等)的时候会通知他的委托对象进行相应处理。

初始化

根据文档中的描述,主要有三个初始化解析器对象的方式。

- (instancetype)initWithContentsOfURL:(NSURL *)url   
- (instancetype)initWithData:(NSData *)data   
- (instancetype)initWithStream:(NSInputStream *)stream

NSXMLParserDelegate

NSXMLParserDelegate是NSXMLParser的委托对象,定义了很多用于处理特定事件的函数,且这些方法都是可选的。接下来我们来看看一些常用的。

//当解析器开始解析文档时
- (void)parserDidStartDocument:(NSXMLParser *)parser

//解析器成功解析完文档时
- (void)parserDidEndDocument:(NSXMLParser *)parser

//当遇到指定元素的开始标识时
- (void)parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
  namespaceURI:(NSString *)namespaceURI
 qualifiedName:(NSString *)qualifiedName
    attributes:(NSDictionary<NSString *,NSString *> *)attributeDict

//当遇到指定元素的结束标识时
- (void)parser:(NSXMLParser *)parser
 didEndElement:(NSString *)elementName
  namespaceURI:(NSString *)namespaceURI
 qualifiedName:(NSString *)qName

//当发生错误时
- (void)parser:(NSXMLParser *)parser
parseErrorOccurred:(NSError *)parseError

//返回当前元素的全部字符串或部分字符数据
//当遇到元素结束标志前应该把所有获取的字符串拼接起来才是完整的数据
- (void)parser:(NSXMLParser *)parser
foundCharacters:(NSString *)string

还有更多的可选方法是某些事件发生时驱动的,可以查阅详细API文档。

解析

解析器开始解析文档操作很简单,只需要发送parse消息就好了。
接下来我们写了一个小例子来简单实现XML文档解析。主要功能就是了解整个数据驱动的解析过程,以及查看我们解析结果。针对不同的XML文档,我们需要有针对性的实现委托对象中各种方法,在方法里对特定元素节点数据进行处理。
首先我们的XML文档内容如下:

<data>  
   <person age="20">zhangsan</person>
   <person age="30">lisi</person>
   <person>wangwu</person>
</data>

我们需要读取出来某个元素节点的特定属性值和元素值。
以下是完整的代码展示。

#import "ViewController.h"

@interface ViewController ()<NSXMLParserDelegate>

@property (strong, nonatomic) NSXMLParser *parser;
@property (strong, nonatomic) NSString *buffer;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.buffer = [[NSString alloc] init];

    self.parser = [[NSXMLParser alloc] initWithContentsOfURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"data" ofType:@"xml"]]];

    self.parser.delegate = self;

    //开始解析
    [self.parser parse];
}

-(void)parserDidStartDocument:(NSXMLParser *)parser
{
    NSLog(@"开始解析文档");
}

-(void)parserDidEndDocument:(NSXMLParser *)parser
{
    NSLog(@"完成文档解析");
}

-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict
{
    NSLog(@"Start Elements: %@", elementName);

    //读取该元素值得属性值
    if ([elementName isEqualToString:@"person"]) {
        NSLog(@"attribute age: %@", attributeDict[@"age"]);
    }
}

-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    //输出读取的该元素的数据
    NSLog(@"Data: %@", self.buffer);
    //清空用于存储该元素值的缓冲区
    self.buffer = [[NSString alloc] init];

    NSLog(@"End Elements: %@", elementName);
}

-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    self.buffer = [self.buffer stringByAppendingString:string];
}

@end

以上就是我们队XML文档的一个简单解析过程,欢迎大家补充指教。

参考资料

乞力马扎罗的雪雪 – iOS开发之解析XML格式数据