NSXMLParser具体解析xml的应用详解

有关NSXMLParser解析类库的基本论述,可查看相关SDK帮助,以下仅仅是具体的应用操作。是以一个图书库应用为例,其Books.xml文档结构如下:

<?xml version="1.0" encoding="UTF-8"?>
 <Books>
   <Book id="1">
       <title>Circumference</title>
       <author>Nicholas Nicastro</author>
       <summary>Eratosthenes and the Ancient</summary>
   </Book>
   <Book id="2">
       <title>Copernicus Secret</title>
       <author>Jack Repcheck</author>
       <summary>How the scientific revolution began</summary>
   </Book>
   <Book id="3">
       <title>Angels and Demons</title>
       <author>Dan Brown</author>
       <summary>Robert Langdon is summoned to a Swiss</summary>
   </Book>
 </Books>
从其文档结构我们可以看出,要定义一个Book实体类描述具体的书籍信息,其中用于存储的相关xml文档元素的实例变量与对应元素同名(本例:title、author、summary),另外还有个bookID实例变量存储Book元素标签的属性id值。具体Book实体类的定义如下:

// Book.h
 #import <UIKit/UIKit.h>
 @interface Book:NSObject {
    NSInteger  bookID;
    NSString    *title;
    NSString    *author;
    NSString    *summary;
 }
 
 @property (nonatomic, readwrite) NSInteger bookID;
 @property (nonatomic, retain) NSString  *title;
 @property (nonatomic, retain) NSString  *author;
 @property (nonatomic, retain) NSString  *summary;
 
 @end
 
 //Book.m
 #import "Book.h"
 @implementation Book
 @synthesize title,author,summary,bookID;
 
 - (void)dealloc {
    [summary release];
    [author release];
    [title release];
    [super dealloc];
 }
 @end
由于例子中的xml文档结构表明会有很多书籍,即Book实体类的实例对象会有很多。所以我们要在应用程序中声明一个可变数组来存储这些信息,如下代码表明:在应用程序委托类中声明了一个可变数组books。

// AppDelegate.h
@interface AppDelegate : NSObject <UIApplicationDelegate> {
    //默认缺省的实例变量

    NSMutableArray  *books;
}
//默认缺省的属性定义

@property (nonatomic, retain) NSMutableArray  *books;
@end
为了代码的清晰,我们可以再声明一个代理类XMLParser,在当NSXMLParser实例对象指定委托时会用到。

// XMLParser.h
#import <UIKit/UIKit.h>

@class AppDelegate, Book;
@interface XMLParser : NSObject {
   NSMutableString *currentElementValue;  //用于存储元素标签的值
   AppDelegate *appDelegate;
   Book *aBook;  //书籍实例
}

- (XMLParser *)initXMLParser; //构造器
@end

// XMLParser.m
- (XMLParser *)initXMLParser {
  [super  init];
  appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
  return self;
}

这整个XMLParser类的实现代码如下:

//XMLParser.m
 #import "XMLParser.h"
 #import "XMLAppDelegate.h"
 #import "Book.h"
  
 @implementation XMLParser
  
 - (XMLParser *) initXMLParser {
  
 [super init];
  
 appDelegate = (XMLAppDelegate *)[[UIApplication sharedApplication] delegate];
  
 return self;
 }
  
 - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
 namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName
 attributes:(NSDictionary *)attributeDict {
  
 if([elementName isEqualToString:@"Books"]) {
 //Initialize the array.
 //在这里初始化用于存储最终解析结果的数组变量,我们是在当遇到Books根元素时才开始初始化,有关此初始化过程也可以在parserDidStartDocument 方法中实现
 appDelegate.books = [[NSMutableArray alloc] init];
 }
 else if([elementName isEqualToString:@"Book"]) {
  
 //Initialize the book.
 //当碰到Book元素时,初始化用于存储Book信息的实例对象aBook
 aBook = [[Book alloc] init];
  
 //Extract the attribute here.
 //从attributeDict字典中读取Book元素的属性
 aBook.bookID = [[attributeDict objectForKey:@"id"] integerValue];
  
 NSLog(@"Reading id value :%i", aBook.bookID);
 }
  
 NSLog(@"Processing Element: %@", elementName);
 }
 /* 可以看出parser:didStartElement:namespaceURI:qualifiedName:attributes方法实现的就是在解析元素开始标签时,进行一些初始化流程 */
  
 - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
 // 当用于存储当前元素的值是空时,则先用值进行初始化赋值
 // 否则就直接追加信息 
 if(!currentElementValue)
 currentElementValue = [[NSMutableString alloc] initWithString:string];
 else
 [currentElementValue appendString:string];
  
 NSLog(@"Processing Value: %@", currentElementValue);
  
 }
 
 // 这里才是真正完成整个解析并保存数据的最终结果的地方
 - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
 namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
  
 if([elementName isEqualToString:@"Books"])
 return;
  
 //There is nothing to do if we encounter the Books element here.
 //If we encounter the Book element howevere, we want to add the book object to the array 遇到Book元素的结束标签,则添加book对象到设置好的数组中。
 // and release the object.
 if([elementName isEqualToString:@"Book"]) {
 [appDelegate.books addObject:aBook];
  
 [aBook release];
 aBook = nil;
 }
 else
 // 不是Book元素时也不是根元素,则用 setValue:forKey为当前book对象的属性赋值
 [aBook setValue:currentElementValue forKey:elementName];
  
 [currentElementValue release];
 currentElementValue = nil;
 }
  
 - (void) dealloc {
  
 [aBook release];
 [currentElementValue release];
 [super dealloc];
 }
  
 @end

只要没有碰到文档结束符,解析器会一而再,再而三的不断呼叫此三个回调函数进行循环:开始初始化book对象并读取有关元素属性,读取子元素和设置它们的值给实体对象,最后不断将实体对象添加到数组中保存。


原文地址:http://www.cnblogs.com/lovecode/archive/2012/01/01/2309687.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值