XML解析主要可以使用CData,libxml2以及NSXMLParser三種方式。
一、CDataXML
- 創建FKBook類
#import <Foundation/Foundation.h>
@interface FKBook : NSObject
@property (nonatomic , assign) NSInteger bookID;
@property (nonatomic , copy) NSString *title;
@property (nonatomic , copy) NSString *author;
@property (nonatomic , copy) NSString *remark;
@end
#import "FKBook.h"
@implementation FKBook
@synthesize bookID,title,author,remark;
@end
- 創建 FKBooksParser 類
#import <Foundation/Foundation.h>
@interface FKBooksParser : NSObject
- (NSArray*) parseXML:(NSString*) xmlName;
@end
#import "FKBooksParser.h"
#import "FKBook.h"
#import "GDataXMLNode.h"
@implementation FKBooksParser
- (NSArray*) parseXML:(NSString*) xmlName {
// 使用NSBundle對象獲取到需要解析的XML文檔的路徑
NSString *path = [[NSBundle mainBundle] pathForResource:xmlName
ofType:@"xml"];
// 使用NSFileHandle對象根據文件路徑獲取到文件
NSFileHandle *file = [NSFileHandle fileHandleForReadingAtPath:path];
// 讀取文件內容返回NSData對象
NSData *data = [file readDataToEndOfFile];
// 根據NSData對象初始化GDataXMLDocument對象
GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:data
options:0 error:nil];
// 如果需要根據XML字符串來初始化GDataXMLDocument對象,則調用如下代碼
// GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithXMLString:xmlStr
// options:0 error:nil];
// 獲取根元素,也就是獲取<books.../>元素
GDataXMLElement *rootElement = [doc rootElement];
// 獲取rootElement下所有<book.../>元素,返回所有<book.../>元素組成的集合
NSArray *bookElements = [rootElement elementsForName:@"book"];
// 初始化一個可變數組,用於存儲將要獲取的所有<book.../>元素的內容
NSMutableArray *books = [[NSMutableArray alloc] init];
// 循環遍歷每一個<book.../>元素
for(GDataXMLElement *bookElement in bookElements)
{
// 初始化FKBook對象
FKBook *book = [[FKBook alloc] init];
// 獲取id屬性值,並且轉成整形
NSInteger bookID = [[[bookElement attributeForName:@"id"]
stringValue] integerValue];
// 獲取title,author,remark元素內容
NSString *title = [[[bookElement elementsForName:@"title"]
objectAtIndex:0] stringValue];
NSString *author = [[[bookElement elementsForName:@"author"]
objectAtIndex:0] stringValue];
NSString *remark = [[[bookElement elementsForName:@"remark"]
objectAtIndex:0] stringValue];
// 將獲取的屬性值和元素內容存儲到FKBook對象的屬性中
book.bookID = bookID;
book.title = title;
book.author = author;
book.remark = remark;
//將每一個Book對象添加到可變數組
[books addObject:book];
}
//返回books集合的副本
return [books copy];
}
@end
- 創建FKViewController : UITableViewController
#import "FKViewController.h"
#import "FKBooksParser.h"
#import "FKBook.h"
@implementation FKViewController
NSArray* books;
- (void)viewDidLoad {
[super viewDidLoad];
// 獲取FKBooksParser實例對象
FKBooksParser* booksParser = [[FKBooksParser alloc] init];
// 解析XML文檔,獲取解析得到的NSArray集合
books =[booksParser parseXML:@"books"];
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
// books屬性包含多少個元素,此處就顯示多少個表格行。
return books.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// 獲取可重用的單元格
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:
@"bookCell" forIndexPath:indexPath];
// 從可重用單元格中根據Tag分別取出3個UILabel控件
UILabel* titleLabel = (UILabel*)[cell viewWithTag:1];
UILabel* authorLabel = (UILabel*)[cell viewWithTag:2];
UILabel* remarkLabel = (UILabel*)[cell viewWithTag:3];
FKBook* book = [books objectAtIndex:indexPath.row];
// 爲3個UILabel設置文本
titleLabel.text = book.title;
authorLabel.text = book.author;
remarkLabel.text = book.remark;
return cell;
}
@end
二、libxml2XML
- 創建FKBook類:
#import <Foundation/Foundation.h>
@interface FKBook : NSObject
@property (nonatomic , assign) NSInteger bookID;
@property (nonatomic , copy) NSString *title;
@property (nonatomic , copy) NSString *author;
@property (nonatomic , copy) NSString *remark;
@end
#import "FKBook.h"
@implementation FKBook
@synthesize bookID,title,author,remark;
@end
- 創建 FKBooksParser 類:
#import <Foundation/Foundation.h>
@interface FKBooksParser : NSObject
- (NSArray*) parseXML:(NSString*) xmlName;
@end
#import "FKBooksParser.h"
#import "FKBook.h"
#import "GDataXMLNode.h"
@implementation FKBooksParser
- (NSArray*) parseXML:(NSString*) xmlName {
// 使用NSBundle對象獲取到需要解析的XML文檔的路徑
NSString *path = [[NSBundle mainBundle] pathForResource:xmlName
ofType:@"xml"];
// 使用NSFileHandle對象根據文件路徑獲取到文件
NSFileHandle *file = [NSFileHandle fileHandleForReadingAtPath:path];
// 讀取文件內容返回NSData對象
NSData *data = [file readDataToEndOfFile];
// 根據NSData對象初始化GDataXMLDocument對象
GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:data
options:0 error:nil];
// 如果需要根據XML字符串來初始化GDataXMLDocument對象,則調用如下代碼
// GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithXMLString:xmlStr
// options:0 error:nil];
// 獲取根元素,也就是獲取<books.../>元素
GDataXMLElement *rootElement = [doc rootElement];
// 獲取rootElement下所有<book.../>元素,返回所有<book.../>元素組成的集合
NSArray *bookElements = [rootElement elementsForName:@"book"];
// 初始化一個可變數組,用於存儲將要獲取的所有<book.../>元素的內容
NSMutableArray *books = [[NSMutableArray alloc] init];
// 循環遍歷每一個<book.../>元素
for(GDataXMLElement *bookElement in bookElements)
{
// 初始化FKBook對象
FKBook *book = [[FKBook alloc] init];
// 獲取id屬性值,並且轉成整形
NSInteger bookID = [[[bookElement attributeForName:@"id"]
stringValue] integerValue];
// 獲取title,author,remark元素內容
NSString *title = [[[bookElement elementsForName:@"title"]
objectAtIndex:0] stringValue];
NSString *author = [[[bookElement elementsForName:@"author"]
objectAtIndex:0] stringValue];
NSString *remark = [[[bookElement elementsForName:@"remark"]
objectAtIndex:0] stringValue];
// 將獲取的屬性值和元素內容存儲到FKBook對象的屬性中
book.bookID = bookID;
book.title = title;
book.author = author;
book.remark = remark;
//將每一個Book對象添加到可變數組
[books addObject:book];
}
//返回books集合的副本
return [books copy];
}
@end
- 創建FKViewController : UITableViewController
#import "FKViewController.h"
#import "FKBooksParser.h"
#import "FKBook.h"
@implementation FKViewController
FKBooksParser* booksParser;
- (void)viewDidLoad {
[super viewDidLoad];
// 獲取FKBooksParser實例對象
booksParser = [[FKBooksParser alloc] init];
// 解析XML文檔
[booksParser readXml:@"books"];
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
// booksParser的books屬性包含多少個元素,此處就顯示多少個表格行。
return booksParser.books.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// 獲取可重用的單元格
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:
@"bookCell" forIndexPath:indexPath];
// 從可重用單元格中根據Tag分別取出3個UILabel控件
UILabel* titleLabel = (UILabel*)[cell viewWithTag:1];
UILabel* authorLabel = (UILabel*)[cell viewWithTag:2];
UILabel* remarkLabel = (UILabel*)[cell viewWithTag:3];
FKBook* book = [booksParser.books objectAtIndex:indexPath.row];
// 爲3個UILabel設置文本
titleLabel.text = book.title;
authorLabel.text = book.author;
remarkLabel.text = book.remark;
NSLog(@"---%d" , book.bookID);
return cell;
}
@end
三、NSXMLParser
#import <Foundation/Foundation.h>
@interface FKXMLPraserDelegate : NSObject <NSXMLParserDelegate>
// 定義一個NSMutableArray集合來保存解析XML文檔得到的數據
@property (nonatomic, strong) NSMutableArray *books;
@end
#import "FKXMLPraserDelegate.h"
#import "FKBook.h"
@implementation FKXMLPraserDelegate
// 定義一個FKBook對象,用於保存正在解析的<book>元素中的數據
FKBook* book;
NSString* currentElementValue;
// 當開始處理某個元素時觸發該方法
- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
attributes:(NSDictionary *)attributeDict {
NSLog(@"開始處理元素 %@" , elementName);
if([elementName isEqualToString:@"books”]) {
// 如果正在處理根元素,在此處初始化存儲解析結果的NSMutableArray集合
self.books = [[NSMutableArray alloc] init];
}
// 如果正在處理<book.../>元素
else if([elementName isEqualToString:@"book"])
{
// 初始化FKBook對象
book = [[FKBook alloc] init];
// 從attributeDict中讀取<book.../>元素的屬性id的值
book.bookID = [[attributeDict objectForKey:@"id"] integerValue];
}
}
// 當開始處理字符串內容時觸發該方法
-(void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
NSLog(@"處理字符串內容:%@",string);
// 如果當前的字符串值不爲nil,保存當前正在處理的元素的值
if(string)
{
currentElementValue = string;
}
}
// 當處理某個元素結束時觸發該方法
-(void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
// 如果處理根元素結束,表明XML文檔處理完成。
if([elementName isEqualToString:@"books"])
{
return;
}
// 如果處理<book.../>元素結束,則將封裝的FKBook對象添加到NSMutableArray集合中
else if([elementName isEqualToString:@"book"])
{
[self.books addObject: book];
book = nil;
}
else
{
// 如果既不是處理<books.../>元素,也不是處理<book.../>元素的時候,
// 則使用KVC方式爲當前FKBook對象的屬性賦值
[book setValue:currentElementValue forKey:elementName];
currentElementValue = nil;
}
}
@end