• NSXMLParser具体解析xml的应用详解


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

     1 <?xml version="1.0" encoding="UTF-8"?>
    2 <Books>
    3 <Book id="1">
    4 <title>Circumference</title>
    5 <author>Nicholas Nicastro</author>
    6 <summary>Eratosthenes and the Ancient</summary>
    7 </Book>
    8 <Book id="2">
    9 <title>Copernicus Secret</title>
    10 <author>Jack Repcheck</author>
    11 <summary>How the scientific revolution began</summary>
    12 </Book>
    13 <Book id="3">
    14 <title>Angels and Demons</title>
    15 <author>Dan Brown</author>
    16 <summary>Robert Langdon is summoned to a Swiss</summary>
    17 </Book>
    18 </Books>

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

     1 // Book.h
    2 #import <UIKit/UIKit.h>
    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 @end
    16
    17 //Book.m
    18 #import "Book.h"
    19 @implementation Book
    20 @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 <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类的实现代码如下:

     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 *)elementName
    18 namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName
    19 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信息的实例对象aBook
    30 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 else
    49 [currentElementValue appendString:string];
    50
    51 NSLog(@"Processing Value: %@", currentElementValue);
    52
    53 }
    54
    55 // 这里才是真正完成整个解析并保存数据的最终结果的地方
    56 - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
    57 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 else
    72 // 不是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对象并读取有关元素属性,读取子元素和设置它们的值给实体对象,最后不断将实体对象添加到数组中保存。






     

  • 相关阅读:
    PHP __autoload()方法真的影响性能吗?
    MYSQL 逻辑架构
    Ajax.dll的初探
    教育技术反思
    祝天下所有的老师教师节快乐
    Asp.net+Xml+js实现无线级下拉菜单
    有调查就有发言权
    控件事件神奇实效
    Inspiration 7.6使用时出现的问题
    最常用的加密类
  • 原文地址:https://www.cnblogs.com/lovecode/p/2309687.html
Copyright © 2020-2023  润新知