首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > XML SOAP >

ASIHTTPRequest跟libxml结合,实现边请求边解析

2012-06-26 
ASIHTTPRequest和libxml结合,实现边请求边解析user namet3 phone15877103548/user namet1 pho

ASIHTTPRequest和libxml结合,实现边请求边解析

<user name="t3" phone="15877103548"/>

<user name="t1" phone="13399459990"/>

</List>

<List Name="好友">

<user name="f2" phone="13828831140"/>

<user name="f3" phone="15886103548"/>

<user name="f1" phone="13019459990"/>

</List>

</root>

也就是说,这是一个通讯录类似的东西。通讯录把电话号码按性质分成不同的组,就像Windows mobile智能手机上的的通讯录,把电话号码按“家庭”、“好友”、“同事”等进行划分。

我们新建一个?BaseXmlParser的子类 TelNoXmlParser ,让这个 TelNoXmlParser 去实现 3 个回调方法:

#import?<Foundation/Foundation.h>

#import?<libxml/tree.h>

#import?"BaseXmlParser.h"

@interface?TelNoXmlParser : BaseXmlParser {

BOOL?loginSuccess?;

NSMutableArray?*?groups?,*?members?;

NSMutableDictionary?*?_group?;

NSDictionary?*?_user?;

}

@end

#import?"TelNoXmlParser.h"

?

?

@implementation?TelNoXmlParser

?

-(?id?)init{

if?(?self?=[?super?init?]) {

//?一个?groups?数组,代表了所有?List

groups?=[[?NSMutableArray?alloc?]?init?];

[?_root?setObject?:?groups?forKey?:?@"items"?];

loginSuccess?=?YES?;

}

return?self?;

}

-(?void?)dealloc{

[?_group?release?],?_group?=?nil?;

[?super?dealloc?];

}

//--------------------------//

#pragma mark -- libxml handler?,主要是?3?个回调方法?--

//--------------------------//

//?解析元素开始标记时触发?,?在这里取元素的属性值以及设置标志变量

- (?void?)startElementLocalName:(?const?xmlChar?*)localname

???prefix:(?const?xmlChar?*)prefix

??URI:(?const?xmlChar?*)URI

nb_namespaces:(?int?)nb_namespaces

???namespaces:(?const?xmlChar?**)namespaces

nb_attributes:(?int?)nb_attributes

??nb_defaulted:(?int?)nb_defaultedslo

???attributes:(?const?xmlChar?**)attributes

{?//?我们关心?8?个元素标签,所以设置了?8?个标志位

????// login_status

????if?(?strncmp?((?char?*)localname,?"login_status"?,?sizeof?(?"login_status"?)) ==?0?) {

??????????loginSuccess?=?NO?;

????????return?;

????}

if?(?loginSuccess?) {

// List

if?(?strncmp?((?char?*)localname,?"List"?,?sizeof?(?"List"?)) ==?0?) {

NSDictionary?* atts=[?self?getAtributes?:attributes?withSize?:nb_attributes];?//?获取?List?的所有属性

_group?=[[?NSMutableDictionary?alloc?]?init?];

members?=[[?NSMutableArray?alloc?]?init?];

[?_group?setObject?:?members?forKey?:?@"members"?];

[?_group?setObject?:[[?NSString?alloc?]?initWithString?:(?NSString?*)[atts?objectForKey?:?@"Name"?]]forKey?:?@"groupname"?];

[?groups?addObject?:?_group?];?//?把?group?加入数组

return?;

}

// user

if?(?strncmp?((?char?*)localname,?"user"?,?sizeof?(?"user"?)) ==?0?) {

NSDictionary?* atts=[?self?getAtributes?:attributes?withSize?:nb_attributes];?//?获取?List?的所有属性

_user?=[[?NSDictionary?alloc?]?initWithDictionary?:atts];

[?members?addObject?:?_user?];

return?;

}

}

}

//?解析元素结束标记时触发

- (?void?)endElementLocalName:(?const?xmlChar?*)localname

??prefix:(?const?xmlChar?*)prefix URI:(?const?xmlChar?*)URI

{

if?(?strncmp?((?char?*)localname,?"root"?,?sizeof?(?"root"?)) ==?0?){?//root?结束时置??login_status?标志

if?(?loginSuccess?) {

[?_root?setObject?:?@"true"?forKey?:?@"login_status"?];

}?else?{

[?_root?setObject?:?@"false"?forKey?:?@"login_status"?];

}

}

if?(?loginSuccess?) {

//?我们还关心?<List>?的结束标记

if?(?strncmp?((?char?*)localname,?"List"?,?sizeof?(?"List"?)) ==?0?) {

[?_group?release?],?_group?=?nil?;?//?回收?_group?对象,以便重复利用

}?else?if?(?strncmp?((?char?*)localname,?"user"?,?sizeof?(?"user"?)) ==?0?){

[?_user?release?],?_user?=?nil?;?//?回收?_user?对象,以便重复利用

}

}

}

//?解析元素体时触发

- (?void?)charactersFound:(?const?xmlChar?*)ch

len:(?int?)len

{??????

//?没有元素体需要关心

}

@end

接下来我们看如何在?ViewController 中使用。

?

四、在?UI 中测试

在?ViewController 中放入一个按钮和一个 WebView,当点击按钮时,请求http服务器,获取通讯录XML 数据,并解析为 Dictionary 对象。把解析结果显示在 WebView 中。

这是按钮的?touch up inside 事件代码:

-(?IBAction?)go{

if?(?_queue?==?nil?){

_queue?= [[?NSOperationQueue?alloc?]?init?];

}

[?button?setEnabled?:?NO?];

[?progress?setProgress?:?0?];

[?webView?loadHTMLString?:?@""?baseURL?:[?NSURL?URLWithString?:?URL?]];

//?构造?xmlparser

TelNoXmlParser?* parser=[[?TelNoXmlParser?alloc?]?init?];

//?把?self?注册为?delegate?,这样?self?必需实现?syncRequestParseStatusNofity:?方法?,?以接收statusChanged?方法

SyncRequestParseOperation?* operation=[[?SyncRequestParseOperation?alloc ]

??initWithURLString?:?URL

??xmlParser?:parser

??delegate?:?self?];

//?把?progress?设置为?progressDelegate?,这样会显示进度

[operation?setProgressDelegate?:?progress?];

[parser?release?];?// opertaion?已?retain?,可以?release

[?_queue?addOperation?:operation];?//?开始处理

[operation?release?];?//?队列已?retain?,可以?release?;

}

这是异步消息到达时的处理代码,当数据接收完时,我们把解析结果在WebView 中显示:

//?实现?statusChanged?通知方法

-(?void?)syncRequestParseStatusNofity:(?id?)sender{

SyncRequestParseOperation?* operation=(?SyncRequestParseOperation?*)sender;

int?status=[operation?status?];

NSLog?(?@"status:%d"?,status);

if?(status==?kRequestStatusFinished?){?//?如数据接收完成

[?button?setEnabled?:?YES?];

NSDictionary?* d=[operation?data?];

[?webView?loadHTMLString?:[d?description?]?baseURL?:[?NSURL?URLWithString?:?URL?]];

}

}

这是程序运行时?WebView 显示效果:

ASIHTTPRequest跟libxml结合,实现边请求边解析

?

注意,当xml 文档比较大时,WebView 的内容是从上到下逐渐刷新的。

这是控制台输出,可以看到服务器响应的数据是被分成很多次下载的:

ASIHTTPRequest跟libxml结合,实现边请求边解析

热点排行