NSXMLParser

1. 使用 NSXMLParser解析XML文档

NSXMLParser 是基于 SAX 的解析器,也就是所谓的“事件驱动”解析器,因此使用 NSXMLParser 解析的关键就是实现 SAX 的时间处理器 --该事件处理器负责处理 NSXMLParser 解析 XML 过程中的各种事件。

NSXMLParser 解析的事件处理采用了委托,因此只要为 NSXMLParser 指定一个 delegate 对象,该对象必须实现 NSXMLParserDelegate 协议

使用 NSXMLParser 解析 XML 文档的步骤:

  1. 创建 NSXMLParser 对象
  2. 为 NSXMLParser 对象指定 delegate ,该 delegate 需要实现 NSXMLParserDelegate 协议
  3. 调用 NSXMLParser 对象的 parse 方法开始解析

2. NSXMLParserDelegate

  • -parserDidStartDocument:
    • 开始处理 XML 文档时激发
  • -parserDidEndDocument:
    • 结束处理 XML 文档时激发
  • -parser:didStartElement:namespaceURI:qualifiedName:attributes:
    • 开始处理 XML 元素时激发
  • -parser:didEndElement:namespaceURI:qualifiedName:
    • 结束处理 XML 元素时激发
  • -parser:didStartMappingPrefix:toURI:
  • -parser:didEndMappingPrefix:
  • -parser:resolveExternalEntityName:systemID:
    • 开始处理外部实体时激发
  • -parser:parseErrorOccurred:
    • 解析出现错误时激发
  • -parser:validationErrorOccurred:
    • XML 文档验证错误时激发
  • -parser:foundCharacters:
    • 解析 XML 文档遇到字符串内容时激发
  • -parser:foundIgnorableWhitespace:
    • 解析 XML 文档遇到空白时激发
  • -parser:foundProcessingInstructionWithTarget:data:
    • 解析XML文档处理指令时激发
  • -parser:foundComment:
    • 处理 XML 文档的注释时激发
  • -parser:foundCDATA:
    • 处理 XML 文档的 CDATA 内容时激发

3. 代码示例:

3.1 XML 文件

<?xml version="1.0" encoding="UTF-8"?>
<books>
<book id="1">
	<title>疯狂iOS讲义</title>
	<author>李刚 编著</author>
	<remark>基于最新版本的iOS 7</remark>
</book>
<book id="2">
	<title>疯狂Java讲义</title>
	<author>李刚 编著</author>
	<remark>本书来自作者3年的Java培训经历,凝结了作者近3000个小时的授课经验</remark>
</book>
<book id="3">
	<title>轻量级Java EE企业应用实战</title>
	<author>李刚 编著</author>
	<remark>本书主要介绍以Spring+Hibernate+Struts2为基础的Java EE应用</remark>
</book>
<book id="4">
	<title>疯狂Android讲义</title>
	<author>李刚 编著</author>
	<remark>本书第一版长期雄踞各网店、书店Android图书销量排行榜前列</remark>
</book>
</books>

3.2 model 类

#import <Foundation/Foundation.h>
@interface FKBook : NSObject
@property (nonatomic , assign) NSInteger bookID;
@property (nonatomic , copy) NSString *title;
@property (nonatomic , copy) NSString *author;
@property (nonatomic , copy) NSString *remark;
@end

3.3 自定义 delegate

.h文件:

#import <Foundation/Foundation.h>

@interface FKXMLPraserDelegate : NSObject <NSXMLParserDelegate>
// 定义一个NSMutableArray集合来保存解析XML文档得到的数据
@property (nonatomic, strong) NSMutableArray *books;
@end

.m文件:

#import "FKXMLPraserDelegate.h"
#import "FKBook.h"

@implementation FKXMLPraserDelegate
// 定义一个FKBook对象,用于保存正在解析的<book>元素中的数据
FKBook* book;
NSString* currentElementValue;
// 当开始处理某个元素时触发该方法
-(void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
attributes:(NSDictionary *)attributeDict
{

NSLog(@"开始处理元素 %@" , elementName);
if([elementName isEqualToString:@"books"])
{
	// 如果正在处理根元素,在此处初始化存储解析结果的NSMutableArray集合
	self.books = [[NSMutableArray alloc] init];
}
// 如果正在处理<book.../>元素
else if([elementName isEqualToString:@"book"])
{
	// 初始化FKBook对象
	book = [[FKBook alloc] init];
	// 从attributeDict中读取<book.../>元素的属性id的值
	book.bookID = [[attributeDict objectForKey:@"id"] integerValue];
}
}
// 当开始处理字符串内容时触发该方法
-(void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
NSLog(@"处理字符串内容:%@",string);
// 如果当前的字符串值不为nil,保存当前正在处理的元素的值
if(string)
{
	currentElementValue = string;
}

}
// 当处理某个元素结束时触发该方法
-(void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
// 如果处理根元素结束,表明XML文档处理完成。
if([elementName isEqualToString:@"books"])
{
	return;
}
// 如果处理<book.../>元素结束,则将封装的FKBook对象添加到NSMutableArray集合中
else if([elementName isEqualToString:@"book"])
{
	[self.books addObject: book];
	book = nil;
}
else
{
	// 如果既不是处理<books.../>元素,也不是处理<book.../>元素的时候,
	// 则使用KVC方式为当前FKBook对象的属性赋值
	[book setValue:currentElementValue forKey:elementName];
	currentElementValue = nil;
}
}
@end

3.4 调用

// 获取要解析的XML文档的所在的URL(使用URL即可解析本地XML文档,也可解析网络XML文档)
NSURL* fileUrl = [[NSBundle mainBundle]
	URLForResource:@"books" withExtension:@"xml"];
// 获取NSXMLParser实例对象
NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:fileUrl];
// 创建NSXMLParser解析的委托对象。
parserDeletage = [[FKXMLPraserDelegate alloc] init];
// 为NSXMLParser指定委托对象,该委托对象就负责处理解析事件
parser.delegate = parserDeletage;
// 开始解析, 解析结果会保存在委托对象的books属性中
[parser parse];
posted @ 2016-04-20 21:30  孙焱焱  阅读(324)  评论(0编辑  收藏  举报