轉載於:http://blog.csdn.net/crayondeng/article/details/8738811html
前一篇文章已經介紹瞭如何經過URL從網絡上獲取xml數據。下面介紹如何將獲取到的數據進行解析。數組
下面先看看xml的數據格式吧!網絡
- <?xml version="1.0" encoding="UTF-8"?>
- <Books>
- <Book id="1">
- <title>Circumference</title>
- <author>Nicholas Nicastro</author>
- <summary>Eratosthenes and the Ancient</summary>
- </Book>
- <Book id="2">
- <title>Copernicus Secret</title>
- <author>Jack Repcheck</author>
- <summary>How the scientific revolution began</summary>
- </Book>
- <Book id="3">
- <title>Angels and Demons</title>
- <author>Dan Brown</author>
- <summary>Robert Langdon is summoned to a Swiss</summary>
- </Book>
- </Books>
顯然在這個xml中包括三本書的一些基本數據:id title author summary 解析的過程就是將這些數據提取出來。
先簡單介紹一下xml數據解析吧。xml數據的解析通常有兩種方式:SAX(Simple API for XML)和DOM (Document Object Model),事件和文檔。app
dom實現的原理是把整個xml文檔一次性讀出,放在一個樹型結構裏。在須要的時候,查找特定節點,而後對節點進行讀或寫。他的主要優點是實現簡單,讀寫平衡;缺點是比較佔內存,由於他要把整個xml文檔都讀入內存,文件越大,這種缺點就越明顯。
sax的實現方法和dom不一樣。他只在xml文檔中查找特定條件的內容,而且只提取須要的內容。這樣作佔用內存小,靈活。
NSXMLParser 實現的是sax方法解析xml文件。dom
下面進入主題介紹如何對xml進行解析:ide
1、將上面的xml數據保存爲Books.xml做爲本地xml數據,並導入項目中。函數
2、因爲book中含有幾個屬性,因此這裏第一個book類。測試
Book.h文件:atom
- #import <Foundation/Foundation.h>
-
- @interface Book : NSObject
-
- @property (nonatomic, readwrite) NSInteger bookID;
- @property (nonatomic, retain) NSString *title;
- @property (nonatomic, retain) NSString *author;
- @property (nonatomic, retain) NSString *summary;
-
- @end
Book.m文件
- #import "Book.h"
-
- @implementation Book
-
- @synthesize bookID;
- @synthesize title;
- @synthesize author;
- @synthesize summary;
-
- @end
3、要實現對xml數據的解析其實是經過實現NSXMLParserDelegate委託中的幾個方法。url
- #pragma mark xmlparser
-
- - (void)parserDidStartDocument:(NSXMLParser *)parser
- {
-
- }
-
- - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
- {
-
- }
-
- - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
- {
-
- }
-
-
- - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
- {
-
- }
-
-
- - (void)parserDidEndDocument:(NSXMLParser *)parser
- {
-
- }
-
- - (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock
- {
-
- }
在實現xml解析過程以上方法中的step3 、四、5是必須的,而step一、5可選。
下面分別介紹:
Step 1: 在開始解析以前的一些準備工做,例如初始化一些存儲變量。在個人這個例子中,使用了一個Book實例變量來存儲一本書(也便是一組信息),一個可變數組來存儲這三本書(即每一組信息都當成這個數組中的一個元素),(這次要注意理解數據變量之間的關係),其餘變量就暫不介紹啦(待會看源代碼就能夠了)。
Step 2: 當解析器遇到xml的根標籤和一組信息的開始標籤時就開始調用這個方法,在這個xml文件中,遇到Books(xml文件的根標籤),Book(一組信息的開始標籤)時就會調用這個方法。那麼也就能夠知道這個方法在程序運行過程當中被調用了屢次。那麼就能夠用 if 語句判斷遇到的是Books仍是Book,而後作一些相應的操做(具體的話待會看源代碼)。
- - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
- {
-
- }
注意其中的參數:elementName表示遇到的標籤,在這個程序中會遇到的是Books和Book; 解析到一個標籤時,開始的 標籤可能會有一些屬性,例如在這裏<Book id="1">
那麼id就是屬性啦,在這個方法中他是用一個字典來保存的即(NSDictionary *)attributeDict,那麼對這個字典操做就能夠獲得你要的value和key啦。
Step 3:當解析器找到開始標籤和結束標籤之間的字符時,就調用這個方法,讀取其中的內容。 注意:這裏讀取到的string在這個函數裏面咱們並不知道是那個屬性的內容,意思就是假如string的內容是Circumference(Book 的title),可是咱們不知道這個是title的內容;那麼在哪裏才知道,而後對它進行存儲操做呢,不要着急,就是Step4啦!
Step 4:當解析器讀到結束標籤時,就會調用這個方法。例如讀到Books,Book,title等。那麼對讀到的標籤進行判斷後就能夠進行存儲操做啦!
- - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
- {
-
- }
這裏標籤參數就是elementName。
Step 5:對整個xml文件解析結束後的一些操做。
Step 6:這個暫不解釋(我尚未用到)。
4、下面就是上代碼的時候啦
.h文件
- #import <UIKit/UIKit.h>
-
- @class AppDelegate,Book;
- @interface ViewController : UIViewController <NSXMLParserDelegate> {
-
- NSMutableString *currentElementValue;
-
- NSMutableArray *books;
-
- Book *aBook;
-
- BOOL storingFlag;
-
- NSArray *elementToParse;
- }
- - (IBAction)xmlButton:(id)sender;
-
- @end
說明:這裏我用一個按鍵來觸發xml解析。
.m文件
說明:
一、其中我用了一些NSLog來輸出相關的信息驗證,實際使用過程當中,去掉就ok啦!
二、結合我上面的解釋和代碼,應該能夠理解整個xml解析的過程的。
三、這裏我用的是本地的xml文件,若是是想進行網絡xml數據的解析的話,那也是很簡單的,就是經過url獲取xml數據替換掉這裏的本地xml,經過url獲取xml能夠參考上一篇博文。