NSXMLParser Demo

在iOS平臺上可用的XML解析方法有很多,如KissXML、Jason等,最近一直在研究,網上可以找到的NSXMLParser Demo很少,大多數代碼十分複雜,下面是使用蘋果提供的NSXMLParser來解析XML的一種方法。適合初學者學習。

例:XML文件如下

<?xml version="1.0" encoding="UTF-8"?>
<response>
    <responseCode>0</responseCode>
    <rows>
        <row>
            <bookImage>mingchaomeiyoushi.png</bookImage>
            <bookTitle>明朝沒有事</bookTitle>
            <bookAuthor>Xong</bookAuthor>
            <bookBroadcaster>哈哈</bookBroadcaster>
            <bookPrice>$0.99</bookPrice>
        </row>
        <row>
            <bookImage>qiyejia.png</bookImage>
            <bookTitle>蘋果</bookTitle>
            <bookAuthor>Apple</bookAuthor>
            <bookBroadcaster>喬布斯</bookBroadcaster>
            <bookPrice>$5.99</bookPrice>
        </row>
    </rows>
</response>

首先介紹一下NSXMLParser這個類,這個類的實例以事件驅動的方式來解析XML,在XML文件中,一旦遇到元素、屬性、CDATA塊和註釋等等就通知通知它的delegate。NSXMLParser只是通知它的delegate去做這些事,本身並不解析XML,所以我們在解析XML的時候,就要用到NSXMLParserDelegate這個protocol。這個protocol中包括很多方法,介紹常用的幾個:

– parser:didStartElement:namespaceURI:qualifiedName:attributes:

當碰到元素頭的時候調用該方法,如當遇到<response>時方法調用

– parser:didEndElement:namespaceURI:qualifiedName:

當碰到元素結束符時調用該方法,如當遇到</response>

– parser:foundCharacters:

當元素含有字符值時,調用該方法

有了這三個方法,我們就可以輕鬆的解析出上述XML文件了,首先我們定義一個名爲XMLParser的類

#import <Foundation/Foundation.h>
@class Book;
@interface XMLParser : NSObject
<NSXMLParserDelegate>
{
    NSString *responseCode;
    NSMutableArray *books;
    NSMutableArray *currentString;
    Book *currentBook;
}
@property (nonatomic, retain) NSMutableArray *books;
@property (nonatomic, retain) NSString *responseCode;
@property (nonatomic, retain) NSMutableArray *currentString;
@property (nonatomic, retain) Book *currentBook;

- (void)addBooks:(Book *)objects;
//開始解析
- (void)startParser:(NSData *)xmlData error:(NSError **)err;

@end

在該類中,實現startParser:error方法來開始開始解析XML

- (void)startParser:(NSData *)xmlData error:(NSError **)err
{
    NSXMLParser *parser = [[[NSXMLParser alloc] initWithData:xmlData] autorelease];
    [parser setDelegate:self];
    [parser setShouldProcessNamespaces:NO];
    [parser setShouldReportNamespacePrefixes:NO];
    [parser setShouldResolveExternalEntities:NO];
    
    currentString = [NSMutableArray array];
    books = [NSMutableArray array];
    //通知delegate解析XML
    [parser parse];
    NSLog(@"responseCode = %@",responseCode);
    NSLog(@"books = %@",books);
}




首先實例化NSXMLParser類,用這個類來發送通知,然後開始解析,首先在XML文件中遇到<response>調用

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
    [currentString removeAllObjects];
}

然後,如上所述

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    if (![string isEqualToString:@""])
        [self.currentString addObject:string];
}

調用,我們可以將讀到的string保存在一個全局變量currentString中來給我們的model賦值,在<response>中並無字符元素,所以string爲空,當我們遇到<responseCode>時,string的值就變爲0了,當我們遇到</responseCode>時

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    if (currentBook == nil) {
        currentBook = [[Book alloc] init];
    }
    if([elementName isEqualToString:@"responseCode"])
    {
        self.responseCode = [self.currentString lastObject];
    }else if([elementName isEqualToString:@"bookImage"]){
        self.currentBook.bookImage = [self.currentString lastObject];
    }else if([elementName isEqualToString:@"bookTitle"]){
        self.currentBook.bookTitle = [self.currentString lastObject];
    }else if([elementName isEqualToString:@"bookAuthor"]){
        self.currentBook.bookAuthor = [self.currentString lastObject];
    }else if([elementName isEqualToString:@"bookBroadcaster"]){
        self.currentBook.bookBroadcaster = [self.currentString lastObject];
    }else if([elementName isEqualToString:@"bookPrice"]){
        self.currentBook.bookPrice = [self.currentString lastObject];
    }else if([elementName isEqualToString:@"row"]){
        [self addBooks:self.currentBook];
        [self setCurrentBook:nil];
    }
}

該方法調用,我們就可以從前面方法中獲取到的currentString來保存XML中元素的值。

這三個方法循環調用,直到XML文件全部解析完畢。

完整代碼地址如下:點擊打開鏈接

以前的代碼寫的比較混亂,很多人說下下來要麼運行不了,要麼有各種問題,重新寫了一個Demo,希望對大家有幫助,上面的連接地址作廢
新的代碼地址如下:點擊打開鏈接

個人理解能力有限,歡迎大家指正






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章