2011-01-11 27 views
2

我有一個應用程序需要從遠程服務器(按地理位置)加載數據並將其顯示在地圖上。來自服務器的提要是基於XML的。我已經成功地完成了這個實現,但想知道我是否能讓自己的生活變得更輕鬆。iOS:訪問XML數據記錄的簡單方法?

目前,我使用的是Google的GDataXML庫,我已經實現了一個用於在後臺獲取遠程數據的庫,並且在完成時或加載過程中會根據需要調用回調函數。

當完整的數據被加載後,我遍歷文檔並將不同的級別轉換爲對象,將該對象添加到NSMutableArray(因爲我想進行延遲加載,所以我想添加更多的請求)然後將該數組傳遞給我的應用程序的下一位,然後解釋併爲我貼上/註釋地圖。

實施例的XML數據(抽象):

<businesses> 
    <business> 
    <name> Fred Bloggs and Co </name> 
    <address> 123 No Street, Nowhere </address> 
    <town> Somesville </town> 
    <county> Someshire </county> 
    <postcode> XX11 1XX </postcode> 
    </business> 
    ..... more records but you get the idea ..... 
</businesses> 

實施例的存儲對象(抽象)

-- businessrecord.h -- 

@interface BusinessRecord : NSObject { 
    NSString *name; 
    NSString *address; 
    NSString *town; 
    NSString *county; 
    NSString *postcode; 
} 

@property (nonatomic, copy) NSString *name; 
@property (nonatomic, copy) NSString *address; 
@property (nonatomic, copy) NSString *town; 
@property (nonatomic, copy) NSString *county; 
@property (nonatomic, copy) NSString *postcode; 

@end 

-- businessrecord.m -- 

@implementation BusinessRecord 

@synthesize name, address, town, county, postcode; 

@end 

權,這樣就可以大概猜測即時手動解析每個XML元素中的每個節點並手動將它們轉移到BusinessRecord對象。

這是特別耗時的,因爲我必須在每個屬性的不同位置編寫三行或更多行代碼。

在GDataXML您訪問的每個元素的東西,如:

NSArray *businesses = [[[xmlRoot elementsForName:@"businesses"] objectAtIndex:0] elementsForName:@"business"]; 
NSMutableArray *businessList = [[NSMutableArray alloc] initWithCapacity: businesses.count]; 

for (int i=0; i<businesses.count; i++) { 
    GDataXMLElement *business = [businesses objectAtIndex: i]; 
    BusinessRecord *busRec = [[BusinessRecord alloc] init]; 
    busRec.name = [[[bus elementsForName:@"name"] objectAtIndex:0] stringValue]; 
    .... etc for each element ... 
    [businessList addObject: busRec]; 
    [busRec release]; 
} 

這一切似乎非常長篇大論對我來說,必須有這樣做的更好的辦法?

我想結束的是在我的XML中的某些隨機訪問數組中的「業務」級別的一切,我不想單獨指定每個元素。

理想的情況下,像在PHP在那裏你可以有一個包含關聯數組一樣順序排列:

$businessList = Array(
    Array(
    "name" => "Fred Bloggs and Co", 
    "address" => "123 No Street", 
    "town" => "Sometown", 
    "county" => "Someshire", 
    "postcode" => "XX11 1XX" 
) 
); 

所以我猜我需要寫一個包裝類,可以解釋一個特定的元素,並得到它的所有子元素都是正確的(即枚舉元素然後對它們進行處理)。

我該如何儲存? NSDictionary的?

也許像(僞代碼):

NSArray *businesses = [[[xmlRoot elementsForName:@"businesses"] objectAtIndex:0] elementsForName:@"business"]; 
NSMutableArray *businessList = [[NSMutableArray alloc] init]; 
[xmlBreakerUpper breakUpXMLAtElement: businesses addToMutableArray: &businessList]; 

有沒有人有任何GDataXML經驗,可以幫我列舉,因爲我不能跟隨稀疏文件。

在這個階段,我並沒有完全依附於GDataXML,我只有兩個類可以依賴它,所以如果有更好的方法。

我在控制服務器輸出,但客戶端對其他數據訪問API有偏好,他們可能會或可能不想稍後實現。

我不需要在此階段將XML發送回服務器,請求目前基於HTTP GET,但稍後人們填寫表單時可能會變爲POST。

所有幫助或推動在正確的方向很好地收到。

回答

1

選項1:

你可以創建自己的init方法爲您businessrecord類接受GDataXMLElement參數,並分析出你需要使用一些XPath表達式,這是對眼睛更舒適一點的值;)

選項2:

爲了實現關聯數組的PHP狀陣列,您可以: 迭代「業務」元素陣列上,並遍歷每個業務元素的兒童,使用子元素名稱爲你的NSMutable的鍵字典業務記錄 - 並將新創建的字典存儲在businessList數組中。

/* THIS IS JUST A QUICK PSEUDO-CODE-ISH SAMPLE */ 
NSArray *businesses = [xmlRoot nodesForXPath:@"//businesses/business" error:nil]; 
NSMutableArray *businessList = [[NSMutableArray alloc] initWithCapacity: businesses.count]; 

GDataXMLElement *business; 

for (business in businesses) 
{ 
    NSMutableDictionary *businessRecord = [[NSMutableDictionary] array]; 

    // iterate over child elements of "business", use element names as keys for businessRecord 
    NSArray *businessChildren = [business children];  
    GDataXMLElement *businessChild; 
    for (businessChild in businessChildren) 
    { 
     [businessRecord setValue:[businessChild value] forKey:[businessChild name]] 
    } 

    [businessList addObject:businessRecord]; 
    [businessRecord release]; 
} 

我偶然發現這篇文章「How To Read and Write XML Documents with GDataXML」時,同時研究了XML解析選項,這是一個堅實的讀,但他們正在分析在特定型號的對象,而不是一個更通用的數據對象,就像你要尋找的。

你應該看看他們的另一篇文章「How To Choose The Best XML Parser For Your iPhone Project」,因爲GDataXML看起來像是過度殺傷。