iPhoneSDK开发136技系列:第24技解析XML

iPhoneSDK开发136技系列:第24技解析XML

本系列文章基于日本最近热卖的《PhoneSDK开发136技》一书的目录和实例代码。由于无法获得此书,因此只能猜测加个人发挥。确切地说应该是一个读码笔记系列。

XML的文件广泛存在于我们的各种服务和应用中。对于XML的解析通常会有如下两种方式:
1.基于数结构的:这种处理方式是将XML的结构看成是树,然后把树的各部分看成一个对象来处理,这就是我们说的DOM (Document Object Model)方式。在iPhone的SDK里包含了一个libxml2的框架(Framework)就能进行DOM解析方式。

2.基于事件的:这种方式通常用于解析基于的事件,SAX解析方式就是这种解析方式的代表。在iPhone开发的,也可以利用这种方式来解析XML。Objectvie-C就提供了专门解析XML的NSXMLParser类。

     这次我们的目标是想从Yahoo新闻的RSS服务中提取到新闻标题。考虑到基于数结构的解析可能会造成比较大的内存压力,这里我们选用NSXMLParser。从Yahoo新闻的RSS服务获取到的XML文档格式如下:

  
  
  
  
  1. <rss version="2.0">   
  2.    
  3. <channel>   
  4. <title>Yahoo! News - Science </title>   
  5. <link>http://headlines.yahoo.co.jp/hl?c=c_sci</link>   
  6. <description>Yahoo! Provide the lastest news in Japan。</description>   
  7. <language>ja</language>   
  8. <copyright>Copyright (C) 2010 Yahoo Japan Corporation. All Rights Reserved.</copyright>   
  9. <lastBuildDate>Wed, 27 Oct 2010 16:45:01 +0900</lastBuildDate>   
  10.    
  11. <image>   
  12. <title>Yahoo! News</title>   
  13. <url>http://i.yimg.jp/images/news/yjnews_s.gif</url>   
  14. <link>http://headlines.yahoo.co.jp/hl</link>   
  15. <width>101</width>   
  16. <height>18</height>   
  17. </image>   
  18.    
  19. <item>   
  20. <title>ソフォスのマルチプラットフォ�`ムのアンチマルウェアが「Hitachi IT Operations Director」に���辏�japan.internet.com)</title>   
  21. <link>http://rd.yahoo.co.jp/rss/l/headlines/secu/inet/*http://headlines.yahoo.co.jp/hl?a=20101027-00000015-inet-secu</link>   
  22. <category>Security</category>   
  23. <pubDate>Wed, 27 Oct 2010 16:41:15 +0900</pubDate>   
  24. </item>   
  25.    
  26. <item>   
  27. ...  
  28. </item>   
  29.    
  30. </channel>   
  31. </rss> 

其中我们关注的是"/rss/channel/item/title"上的新闻标题。

NSXMLParser 的实例以事件驱动的方式对XML文档进行解析。NSXMLParser在处理XML文档的过程中当遇到一些要素(元素、属性、CDATA块、评论等)时会通知它的委托,而自身不对解析的要素进行任何处理。同时它也会报告错误。相关实现的代码如下:

  
  
  
  
  1. @interface SampleParser : NSObject  
  2. {  
  3.     NSMutableArray *tagPath;  
  4.     NSMutableArray *tagPathAttributs;  
  5.     NSMutableString *recordingText;  
  6. }  
  7. @end  
  8.  
  9. @implementation SampleParser  
  10. +(void) parseTest {  
  11.     // 取得获取Yahoo新闻标题的RSS  
  12. NSString *urlStr = @"http://headlines.yahoo.co.jp/rss/sci.xml";  
  13. // 使用NSXMLParser三部曲:生成、设置代理和开始解析  
  14.     NSXMLParser *parser = [[NSXMLParser alloc]  
  15.         initWithContentsOfURL:[NSURL URLWithString:urlStr]];  
  16.     SampleParser *sp = [[SampleParser alloc]init];  
  17.  
  18.     [parser setDelegate:sp];  
  19.     [parser parse];  
  20.     NSError *parseError = [parser parserError];  
  21.     if (parseError ) {  
  22.         NSLog(@"Err %@",[parseError description]);  
  23.     }  
  24.     NSLog(@"parseEnd");  
  25. }  
  26.  
  27. -(id)init {  
  28.     if (self = [super init]) {  
  29.         tagPath = [[[NSMutableArray alloc]init]retain];  
  30.         tagPathAttributs = [[[NSMutableArray alloc]init]retain];  
  31.         [tagPath addObject:@""];  
  32.         [tagPathAttributs addObject:[NSDictionary dictionary]];  
  33.     }  
  34.     return self;  
  35. }  
  36. -(void)dealloc {  
  37.     [tagPath release];  
  38.     [tagPathAttributs release];  
  39.     [super dealloc];  
  40. }  
  41.  
  42. // 获取Tag的全路径  
  43. -(NSString*)tagFullPath {  
  44.     return [tagPath componentsJoinedByString:@"/"];  
  45. }  
  46.  
  47. // 开始解析  
  48. - (void)parser:(NSXMLParser *)parser  
  49. didStartElement:(NSString *)elementName  
  50. namespaceURI:(NSString *)namespaceURI  
  51. qualifiedName:(NSString *)qName  
  52. attributes:(NSDictionary *)attributeDict  
  53. {  
  54.     NSString *tag = [elementName copy];  
  55.     [tagPath addObject:tag];  
  56.     [tagPathAttributs addObject:[attributeDict copy]];  
  57.  
  58.     //开始获取文字列  
  59.     NSString *tagFullPath = [self tagFullPath];  
  60.     if ([tagFullPath hasPrefix:@"/rss/channel/item/title"]) {  
  61.         recordingText = [[[NSMutableString alloc]init] autorelease];  
  62.         [recordingText appendString:@""];  
  63.     }  
  64. }  
  65.  
  66. // Tag的完成  
  67. - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName  
  68.    namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {  
  69.     //结束获取文字列  
  70.     NSString *tagFullPath = [self tagFullPath];  
  71.     if ([tagFullPath hasPrefix:@"/rss/channel/item/title"]) {  
  72.         NSLog(@"Title:%@",recordingText);  
  73.         recordingText = nil;  
  74.     }  
  75.  
  76.     [tagPath removeLastObject];  
  77.     [tagPathAttributs removeLastObject];  
  78. }  
  79.  
  80. - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {  
  81.     // 记录所取得的文字列  
  82.     if (recordingText!=nil) {  
  83.         [recordingText appendString:string];  
  84.     }  
  85. }  
  86. - (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock{  
  87.     //NSLog(@"cData:%@",[NSString stringWithUTF8String:[CDATABlock bytes]]);  
  88. }  
  89. @end  

 

你可能感兴趣的:(移动开发,职场,xml解析,休闲,NSXMLParser)