• 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];
  • 相关阅读:
    从 Objective-C 里的 Alloc 和 AllocWithZone 谈起
    设计模式(26)
    iOS目录结构
    IOS didReceiveMemoryWarning 的那些事
    iOS多线程编程:线程同步总结
    我要进大厂之大数据Hadoop HDFS知识点(2)
    我要进大厂之大数据Hadoop HDFS知识点(1)
    我要进大厂之大数据ZooKeeper知识点(2)
    我要进大厂之大数据ZooKeeper知识点(1)
    rabbitmq使用延迟时报异常
  • 原文地址:https://www.cnblogs.com/sunyanyan/p/5414523.html
Copyright © 2020-2023  润新知