您的位置:首页 > 职场人生

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

2010-10-27 16:14 435 查看
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文档格式如下:
<rss version="2.0">

<channel>
<title>Yahoo! News - Science </title>
<link>http://headlines.yahoo.co.jp/hl?c=c_sci</link>
<description>Yahoo! Provide the lastest news in Japan。</description>
<language>ja</language>
<copyright>Copyright (C) 2010 Yahoo Japan Corporation. All Rights Reserved.</copyright>
<lastBuildDate>Wed, 27 Oct 2010 16:45:01 +0900</lastBuildDate>

<image>
<title>Yahoo! News</title>
<url>http://i.yimg.jp/images/news/yjnews_s.gif</url>
<link>http://headlines.yahoo.co.jp/hl</link>
<width>101</width>
<height>18</height>
</image>

<item>
<title>ソフォスのマルチプラットフォームのアンチマルウェアが「Hitachi IT Operations Director」に対応(japan.internet.com)</title>
<link>http://rd.yahoo.co.jp/rss/l/headlines/secu/inet/*http://headlines.yahoo.co.jp/hl?a=20101027-00000015-inet-secu</link>
<category>Security</category>
<pubDate>Wed, 27 Oct 2010 16:41:15 +0900</pubDate>
</item>

<item>
...
</item>

</channel>
</rss>

其中我们关注的是"/rss/channel/item/title"上的新闻标题。
NSXMLParser 的实例以事件驱动的方式对XML文档进行解析。NSXMLParser在处理XML文档的过程中当遇到一些要素(元素、属性、CDATA块、评论等)时会通知它的委托,而自身不对解析的要素进行任何处理。同时它也会报告错误。相关实现的代码如下:
@interface SampleParser : NSObject
{
NSMutableArray *tagPath;
NSMutableArray *tagPathAttributs;
NSMutableString *recordingText;
}
@end

@implementation SampleParser
+(void) parseTest {
// 取得获取Yahoo新闻标题的RSS
NSString *urlStr = @"http://headlines.yahoo.co.jp/rss/sci.xml";
// 使用NSXMLParser三部曲:生成、设置代理和开始解析
NSXMLParser *parser = [[NSXMLParser alloc]
initWithContentsOfURL:[NSURL URLWithString:urlStr]];
SampleParser *sp = [[SampleParser alloc]init];

[parser setDelegate:sp];
[parser parse];
NSError *parseError = [parser parserError];
if (parseError ) {
NSLog(@"Err %@",[parseError description]);
}
NSLog(@"parseEnd");
}

-(id)init {
if (self = [super init]) {
tagPath = [[[NSMutableArray alloc]init]retain];
tagPathAttributs = [[[NSMutableArray alloc]init]retain];
[tagPath addObject:@""];
[tagPathAttributs addObject:[NSDictionary dictionary]];
}
return self;
}
-(void)dealloc {
[tagPath release];
[tagPathAttributs release];
[super dealloc];
}

// 获取Tag的全路径
-(NSString*)tagFullPath {
return [tagPath componentsJoinedByString:@"/"];
}

// 开始解析
- (void)parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
attributes:(NSDictionary *)attributeDict
{
NSString *tag = [elementName copy];
[tagPath addObject:tag];
[tagPathAttributs addObject:[attributeDict copy]];

//开始获取文字列
NSString *tagFullPath = [self tagFullPath];
if ([tagFullPath hasPrefix:@"/rss/channel/item/title"]) {
recordingText = [[[NSMutableString alloc]init] autorelease];
[recordingText appendString:@""];
}
}

// Tag的完成
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
//结束获取文字列
NSString *tagFullPath = [self tagFullPath];
if ([tagFullPath hasPrefix:@"/rss/channel/item/title"]) {
NSLog(@"Title:%@",recordingText);
recordingText = nil;
}

[tagPath removeLastObject];
[tagPathAttributs removeLastObject];
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
// 记录所取得的文字列
if (recordingText!=nil) {
[recordingText appendString:string];
}
}
- (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock{
//NSLog(@"cData:%@",[NSString stringWithUTF8String:[CDATABlock bytes]]);
}
@end
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息