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

  • 博主:易飞扬
  • 原文链接 : http://www.yifeiyang.net/iphone-web-development-techniques-of-the-chapter-1-parsing-xml/
  • 转载请保留上面文字。
  • 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文档由网络下载,然后解析,比较的结果如下 :

    下载用时 解析用时 合计
    NSXMLParser 1.419s 5.525s 7.134s
    libxml2 2.520s 2.247s 2.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];

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

    你可能感兴趣的:(iPhone开发)