2011-01-11 47 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看起来像是过度杀伤。

相关问题