NSXMLParser具体解析xml的应用详解

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

1 2 3 4 Circumference 5 Nicholas Nicastro 6

Eratosthenes and the Ancient 7 8 9 Copernicus Secret10 Jack Repcheck11 How the scientific revolution began12 13 14 Angels and Demons15 Dan Brown16 Robert Langdon is summoned to a Swiss17 18

从其文档结构我们可以看出,要定义一个Book实体类描述具体的书籍信息,其中用于存储的相关xml文档元素的实例变量与对应元素同名(本例:title、author、summary),另外还有个bookID实例变量存储Book元素标签的属性id值。具体Book实体类的定义如下:

1 // Book.h 2 #import 3 @interface Book:NSObject { 4 NSInteger bookID; 5 NSString *title; 6 NSString *author; 7 NSString *summary; 8 } 9 10 @property (nonatomic, readwrite) NSInteger bookID;11 @property (nonatomic, retain) NSString *title;12 @property (nonatomic, retain) NSString *author;13 @property (nonatomic, retain) NSString *summary;14 15 @end16 17 //Book.m18 #import "Book.h"19 @implementation Book20 @synthesize title,author,summary,bookID;21 22 - (void)dealloc {23 [summary release];24 [author release];25 [title release];26 [super dealloc];27 }28 @end

由于例子中的xml文档结构表明会有很多书籍,即Book实体类的实例对象会有很多。所以我们要在应用程序中声明一个可变数组来存储这些信息,如下代码表明:在应用程序委托类中声明了一个可变数组books。

// AppDelegate.h@interface AppDelegate : NSObject { //默认缺省的实例变量 NSMutableArray *books;}//默认缺省的属性定义@property (nonatomic, retain) NSMutableArray *books;@end

为了代码的清晰,我们可以再声明一个代理类XMLParser,在当NSXMLParser实例对象指定委托时会用到。

// XMLParser.h#import @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类的实现代码如下:

1 //XMLParser.m 2 #import "XMLParser.h" 3 #import "XMLAppDelegate.h" 4 #import "Book.h" 5 6 @implementation XMLParser 7 8 - (XMLParser *) initXMLParser { 9 10 [super init];11 12 appDelegate = (XMLAppDelegate *)[[UIApplication sharedApplication] delegate];13 14 return self;15 }16 17 - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName18 namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName19 attributes:(NSDictionary *)attributeDict {20 21 if([elementName isEqualToString:@"Books"]) {22 //Initialize the array.23 //在这里初始化用于存储最终解析结果的数组变量,我们是在当遇到Books根元素时才开始初始化,有关此初始化过程也可以在parserDidStartDocument 方法中实现24 appDelegate.books = [[NSMutableArray alloc] init];25 }26 else if([elementName isEqualToString:@"Book"]) {27 28 //Initialize the book.29 //当碰到Book元素时,初始化用于存储Book信息的实例对象aBook30 aBook = [[Book alloc] init];31 32 //Extract the attribute here.33 //从attributeDict字典中读取Book元素的属性34 aBook.bookID = [[attributeDict objectForKey:@"id"] integerValue];35 36 NSLog(@"Reading id value :%i", aBook.bookID);37 }38 39 NSLog(@"Processing Element: %@", elementName);40 }41 /* 可以看出parser:didStartElement:namespaceURI:qualifiedName:attributes方法实现的就是在解析元素开始标签时,进行一些初始化流程 */42 43 - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {44 // 当用于存储当前元素的值是空时,则先用值进行初始化赋值45 // 否则就直接追加信息 46 if(!currentElementValue)47 currentElementValue = [[NSMutableString alloc] initWithString:string];48 else49 [currentElementValue appendString:string];50 51 NSLog(@"Processing Value: %@", currentElementValue);52 53 }54 55 // 这里才是真正完成整个解析并保存数据的最终结果的地方56 - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName57 namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {58 59 if([elementName isEqualToString:@"Books"])60 return;61 62 //There is nothing to do if we encounter the Books element here.63 //If we encounter the Book element howevere, we want to add the book object to the array 遇到Book元素的结束标签,则添加book对象到设置好的数组中。64 // and release the object.65 if([elementName isEqualToString:@"Book"]) {66 [appDelegate.books addObject:aBook];67 68 [aBook release];69 aBook = nil;70 }71 else72 // 不是Book元素时也不是根元素,则用 setValue:forKey为当前book对象的属性赋值73 [aBook setValue:currentElementValue forKey:elementName];74 75 [currentElementValue release];76 currentElementValue = nil;77 }78 79 - (void) dealloc {80 81 [aBook release];82 [currentElementValue release];83 [super dealloc];84 }85 86 @end

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

枳柜是什么意思
购买我附近的七白膏免费送货