在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,希望對大家有幫助,上面的連接地址作廢
新的代碼地址如下:點擊打開鏈接
個人理解能力有限,歡迎大家指正