网上找到解析XML方法
iPhone开发技巧之网络篇(1)— 解析XML
16四/10
iPhone开发技巧之网络篇(1)--- 解析XML 开发 iPhone 上的网络应用程序的时候时常需要解析XML文档,比如web应用中的SOAP,REST,RSS信息等都是以XML为基础的。掌握XML解析的技术是很重要的。这里我将为大家介绍一下iPhone下解析XML的几种方法,并比较其性能。 iPhone的XML库iPhone中标准的XML解析库有两个,分贝是libxml2和NSXMLParser。 libxml2由Gnome项目开发、由于是MIT的开放协议,已经移植到许多的平台,在iPhone上也能使用。 libxml2的特点是比较快。另外作为最基本的XML解析器,提供SAX和DOM解析。并且它对应的XML标准最多,比如名称空间、XPath、XPointer、HTML、XInclude、XSLT、XML Schema、Relax NG等。另外它是用C语言写的,比较高速。 NSXMLParser是Cocoa中内含的XML解析器。它只提供了SAX解析的功能。因为是Cocoa的一部分、并且API是Objective-C的,所以与Mac系统兼容性强,使用也相对简单。 XML解析与内存占用由于iPhone也是一种嵌入式设备,所以与其他的嵌入式设备一样,同样有内存,CPU等资源占用问题。所以在选择代码库的时候需要考虑性能与内存占用的问题。 一般XML的解析器有SAX解析和DOM解析两种方式、相比之下SAX比较小巧精干,耗费的内存小。这是因为其设计思想与DOM完全不一样,一边得到数据一边解析,由回调的方式通知得到的数据,没有了DOM树的概念。 现在的iPhone 3G搭载的RAM是128MB(3GS是256MB)。其中有iPhone OS本身使用的、还有根据用于使用情况不同,比如MP3,邮件,Safari等常驻程序等。基本上自己的程序可使用的内存大小是10MB左右的空间。 开发XML解析程序的时候,需要注意到XML文件一般都比较大,如果使用DOM的话,消费的内存量肯定很多。所以在iPhone中上面这两种解析器只能使用SAX的解析方式。DOM方式只能在模拟器上使用(比如NSXMLDocument类),放到实际设备上就不管用了。(不过,在下面的章节中我将介绍一种使用DOM的第三方方法,对于小的XML文档还是值得一用的。) libxml2 vs NSXMLParser一般是使用libxml2的SAX解析器呢,还是使用NSXMLParser能,我们通过下面的SDK中附属的例子XMLPerformance来做个测试。 相同的XML文档由网络下载,然后解析,比较的结果如下 :
可以看到,libxml2比NSXMLParser快得多。这与它们处理的方式有些关系,NSXMLParser中调用SAX API的时候,参数是作为字符串传递的,需要先转换为NSString或者是NSDictionary对象,并且它不像libxml2那样是一边下载一边解析,需要整个文件下载完了才开始解析。所以说建议一般使用libxml2。 NSXMLParser的例子解析的XML代码例子如下: 代码如下: 实际使用的时候除最后两行以外,所有的当如一个类中,最后两个是启动该类的代码。 libxml2的例子项目中添加libxml首先需要将libxml添加到你的工程项目中。 我们知道,当向项目中添加外部库的时候,如果是程序框架的,比如UIKit.framework,Foundation.framework等放在Sysytem/Library/Frameworks 目录下。SDK放在 /Developer/Platforms/iPhoneOS.platform/Developer/SDKs 目录下。 但是由于libxml是UNIX的库、位于SDK文件夹的usr/lib下。头文件位于 usr/include 下。 在 libxml 目录下将 libxml2.2.dylib(或更高版本)添加到项目中。将头文件路径 usr/include/libxml2 也添加到包含路径中。 以下是libxml2.2.dylib的路径 /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS${VER}sdk/usr/lib/libxml2.2.dylib 以下是头文件的路径 /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS${VER}.sdk/usr/include/libxml2 libxml中的SAX解析器用过SAX解析器的朋友都知道,SAX就是事先登录一些处理函数,当XML解析到属性或要素的时候,回调登录的处理函数。 以下是一个例子,DownloadOperation实现网络文件的下载,同时交给libxml2的SAX解析器处理: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
DownloadOperation.h #import <Foundation/Foundation.h> <libxml/tree.h> @interface DownloadOperation : NSOperation { NSURLRequest* _request; NSURLConnection* _connection; xmlParserCtxtPtr _parserContext; BOOL _isExecuting,_isFinished; BOOL _isChannel,_isItem; NSMutableDictionary* _channel; NSMutableDictionary* _currentItem; NSMutableString* _currentCharacters; } Property @property (readonly) NSDictionary* channel; Initialize - (id)initWithRequest:(NSURLRequest*)request; @end | ||||||||||||
首先、#import了libxml/tree.h头文件。然后声明了一个 xmlParserCtxtPtr 变量作为解析器的实例。
连接开始的时候(start函数)使用 xmlCreatePushParserCtxt 创建解析器实例,这里注意第二个参数,将DownloadOperation 的实例传到解析器内,这个正是回调函数中的第一个参数 — 作为回调函数的句柄调用类成员函数(当然,不使用实例方法,将回调函数设置成类方法也是可行的。但是当你使用到DownloadOperation中的成员等会有些不便,所以从OO的角度出发,还是传递回调函数的对象实例为佳)。
开始下载的时候,因为数据是顺序得到的,所以一边下载,一边用 xmlParseChunk 传递给解析器。
libxml的SAX句柄函数在xmlSAXHandler结构中定义。这个构造体内有30多个句柄定义,一般我们只需要登录其中几个就够了。比如例子中的 startElementNsSAX2Func、endElementNsSAX2Func、charactersSAXFunc 等,他们的定义如下:
最后,因为用SAX解析,需要知道当前解析的位置,所以标记参数需要合理的使用。
使用DOM解析
上面我们已经介绍了,iPhone 中的XML解析器都是SAX的,如果仅仅对于比较小的XML文档,或者说想得到DOM树结构的XML文档来说,使用DOM解析还是有一定价值的(比如针对简单的SOAP,REST文档解析等)。
Google Data APIs
这里介绍一种使用第三方类库的方法,具体见这里。其实说是第三方类库,其实还是使用了libxml2,所以前期库文件和头文件的设置与上面libxml2是一致的。并将 -lxml2 加到link的设置中。
使用的时候,先从这里下载并解冻 Google Data APIs Objective-C Client Library,然后将下面解开的文件拷贝到项目中去。
解析的例子如下:
下面就是使用方法了,DOM的API使用起来还是感觉便利些:
TouchXML
TouchXML与上面的Google Data的XML解析器类似,也是基于libxml2的一款第三方DOM解析器。设置是一样的。
下面开一个例子(从网上摘抄的):
KissXML
KissXML据说速度比 TouchXML 快些,暂时还没有试过,用兴趣的朋友可以试试。例子如下:
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!