iOS開發之解析XML數據

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

原文鏈接:http://my.oschina.net/khakiloveyty/blog/396671

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