這兩天開始實作天氣APP,
程式架構的部分就不多說了,
由於Yahoo的WOEID及天氣資訊是以XML及RSS的方式提供,
所以必須實作XML Parser把所需要的資料解析出來,
這一篇主要是說明怎麼實作XML Parser的功能,

XML的格是相當複雜,
這邊只能針對簡易的兩種基本格式作處理,
第一種:
<XML>
   <TagA>ValueA</TagA>
   <TagB>ValueB</TagB>
   <TagC>ValueA</TagC>
</XML>

第二種:
<XML>
   <Tag:A ValueA1=A1 ValueA2=A2 ValueA3=A3/>
   <Tag:B ValueB1=B1 ValueB2=B2 ValueB3=B3/>
   <Tag:C ValueC1=C1 ValueA2=C2 ValueC3=C3/>
</XML>

我使用的是Object-C提供的NSXMLParser,
市場上還有許多3rd Party提供的API,
由興趣的可以參考這一篇文章,
由於我所處理的資料量並不是太龐大,
所以用NSXMLParser已經足夠了,

使用NSXMLParser的步驟大致如下,
1.宣告NSXMLParser變數
   常用的有兩種,如果XML已存成檔案或放在NSData檔案中,則使用:
   NSXMLParser *My_XMLParser = [[NSXMLParser alloc] initWithData:(NSData *)];
   如果直接由網路上URL讀取XML後直接解析,則使用:
   NSXMLParser *My_XMLParser = [[NSXMLParser alloc] initWithContentOfURL:(NSURL *)];
2.實作NSXMLParser delegate
   很多寫Object-C的人對於delegate總是一知半解,我建議花點時間了解一下,這邊就不多介紹,原則上我們需要告訴系統由誰來代理(實際執 行)Parser XML的工作,所以在這裡要宣告一個新的Class,直接使用Xcode產生一個NSObject的Class,我的範例如下:
#import <Foundation/Foundation.h>
//Global variant

@interface XMLParser : NSObject{
}

@end

這是基本的CLass,還需要加點工讓他可以做個稱職的delegate,
#import <Foundation/Foundation.h>

@interface XMLParser : NSObject <NSXMLParserDelegate> {
   XMLParser *parser;
}
- (XMLParser *) initXMLParser;

@end
接著別忘了在.m中實作initXMLParser function
- (XMLParser *) initXMLParser{
   self = super init;
   return self;
}

在實作delegate之前,先來看看主程序的程式碼
  //宣告XMLParser變數
  NSXMLParser *My_XMLParser = [[NSXMLParser alloc] initWithData:(NSData *)];
 //宣告delegate變數
  XMLParser *parser = [[XMLParser alloc] initXMLParser]
  //設定delegate
  [My_XMLParser setDelegate: parser];
  基本工作準備完畢,現再來實作如何取得XML資料

3.在NSXMLParser delegate中處理XML資料
  .h程式碼
#import <Foundation/Foundation.h>

@interface XMLParser : NSObject <NSXMLParserDelegate> {
   XMLParser *parser;
   int AddXMLflag;
}
- (XMLParser *) initXMLParser;
//function 1
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict;
//function2
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string;
//function3
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
 namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName;

@end

NSXMLParser主要用到3個function來取得資料,
function1是在找到Element(tag)時要做什麼事,
function2是在找到Element(tag)後要做什麼事,
function3是在找到Element(tag)結束時要做什麼事,

所以如果要處理上面第一種XML格式,主要要在function2中取得Value,
程式碼如下:
//為了控制是否已經讀取到我們要的Tag,然後讓function2可以取值,所以設定一個變數來控制
ReadFlag = 0;
//function1
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
  if([elementName isEqualToString:@"TagA"] && ReadFlag==0;){
     ReadFlag = 1;
   }
}

//function2
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
   if(ReadFlag == 1){
      //OutputString記得要宣告
      OutputString = string;
   }
}

//function3
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
 namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
   if([elementName isEqualToString:@"TagA"] && ReadFlag==1;){
     ReadFlag = 0;
   }
}

所以如果要處理上面第二種XML格式,主要要在function1中取得Value,function2及function3不需要做特別處理,
程式碼如下:
//function1
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
  //elementName必須要包含:A
  if([elementName isEqualToString:@"Tag:A"]){
      for(id key in attribuiteDict){
         NSLOG(@"\n AttributeDict Key = %@, Value = %@\n",key,[attributeDict objectForKey:key]);
      }
   }
}

//function2
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
}

//function3
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
 namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
}
Log會印出
 AttributeDict Key = ValueA1, Value = A1
 AttributeDict Key = ValueA2, Value = A2
 AttributeDict Key = ValueA3, Value = A3

以上簡單介紹兩種XML格式的Parser,希望對大家有點幫助

arrow
arrow

    鴨蛋王 發表在 痞客邦 留言(2) 人氣()