您的位置:首页 > 理论基础 > 计算机网络

iPhone开发技巧之网络篇(1)— 解析XML A

2011-02-18 09:27 477 查看

博主:易飞扬

原文链接 : http://www.yifeiyang.net/iphone-web-development-techniques-of-the-chapter-1-parsing-xml/

转载请保留上面文字。

iPhone 的XML库XML 解析与内存占用libxml2 vs NSXMLParserNSXMLParser 的例子libxml2 的例子项 目中添加libxmllibxml 中的SAX解析器使 用DOM解析Google Data APIsTouchXMLKissXML
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文档由网络下载,然后解析,比较的结果如下 :

下载用时解析用时合计
NSXMLParser1.419s5.525s7.134s
libxml22.520s2.247s2.646s
可以看到,libxml2比NSXMLParser快得多。这与它们处理的方式有些关系,NSXMLParser中调用SAX API的时候,参数是作为字符串传递的,需要先转换为NSString或者是NSDictionary对象,并且它不像libxml2那样是一边下载一边 解析,需要整个文件下载完了才开始解析。所以说建议一般使用libxml2。

NSXMLParser的例子

解析的XML代码例子如下:

1
2
3
4
5

<?xml version="1.0" encoding="UTF-8"?>
<users>
<user name="hoge" age="20" />
<user name="fuga" age="30" />
</users>

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

static NSString *feedURLString = @"http://www.yifeiyang.net/test/test.xml";

- (void)parserDidStartDocument:(NSXMLParser *)parser
{
// 解析开始时的处理
}

- (void)parseXMLFileAtURL:(NSURL *)URL parseError:(NSError **)error
{
NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:URL];
[parser setDelegate:self];
[parser setShouldProcessNamespaces:NO];
[parser setShouldReportNamespacePrefixes:NO];
[parser setShouldResolveExternalEntities:NO];
[parser parse];
NSError *parseError = [parser parserError];
if (parseError && error) {
*error = parseError;
}
[parser release];
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
// 元素开始句柄
if (qName) {
elementName = qName;
}
if ([elementName isEqualToString:@"user"]) {
// 输出属性值
NSLog(@"Name is %@ , Age is %@", [attributeDict objectForKey:@"name"], [attributeDict objectForKey:@"age"]);
}
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
// 元素终了句柄
if (qName) {
elementName = qName;
}
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
// 取得元素的text
}

NSError *parseError = nil;
[self parseXMLFileAtURL:[NSURL URLWithString:feedURLString] parseError:&parseError];

实际使用的时候除最后两行以外,所有的当如一个类中,最后两个是启动该类的代码。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: