xml多线程解析,简单易懂的例⼦
抽空讲⼀下以前做的xml解析,⾃⼰的⼯作先扔⼀边吧!
先看看要解析的数据格式
<?xml version='1.0' encoding='UTF-8'?>
<chats>
<chat>
<speaker><![CDATA[self]]></speaker>
<text><![CDATA[hello]]></text>
</chat>
<chat>
<speaker><![CDATA[other]]></speaker>
<text><![CDATA[world]]></text>
</chat>
<chat>
<speaker><![CDATA[other1]]></speaker>
<text><![CDATA[world1]]></text>
</chat>
<chat>
<speaker><![CDATA[other1]]></speaker>
<text><![CDATA[world1]]></text>
</chat>
<chat>
<speaker><![CDATA[other2]]></speaker>
<text><![CDATA[world2]]></text>
</chat>
<chat>
<speaker><![CDATA[other3]]></speaker>
<text><![CDATA[world3]]></text>
</chat>
<chat>网络上xml是什么意思
<speaker><![CDATA[other4]]></speaker>
<text><![CDATA[world4]]></text>
</chat>
<chat>
<speaker><![CDATA[other5]]></speaker>
<text><![CDATA[world5]]></text>
</chat>
</chats>
把它放在了⼀个叫l的⽂件中,再拖到⼯程⾥⾯来
这个解析只需要⼀个类就够了,下⾯来看看头⽂件
#import <UIKit/UIKit.h>
@interface xmlParseViewController : UIViewController<NSXMLParserDelegate> {//注意要添加代理!!!
NSMutableArray        *chatArray;
NSString            *chatFile;
NSMutableDictionary    *currentChatInfo;
NSMutableString    *currentString;
BOOL            storingCharacters;
IBOutlet UITableView *table;
}
@end
下⾯来看看.m⽂件
#import"xmlParseViewController.h"
@implementation xmlParseViewController
static NSString *kName_Chats = @"chats";
static NSString *kName_Chat = @"chat";
static NSString *kName_Speaker = @"speaker";
static NSString *kName_Text = @"text";
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *) qualifiedName attributes:(NSDictionary *)attributeDict { if ([elementName isEqualToString:kName_Chats]) {
[chatArray removeAllObjects];//开始之前先将数组元素移除
} else if ([elementName isEqualToString:kName_Chat]) {
[currentChatInfo removeAllObjects];//字典元素也要移除
} else if ([elementName isEqualToString:kName_Speaker] ||
[elementName isEqualToString:kName_Text]) {
[currentString setString:@""];//将数组也置为空,注意写法
storingCharacters = YES;//此处开始解析
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if ([elementName isEqualToString:kName_Chats]) {
//这⾥什么也不做
} else if ([elementName isEqualToString:kName_Chat]) {
[chatArray addObject:[NSDictionary dictionaryWithDictionary:currentChatInfo]];
//把字典添加进数组
} else if ([elementName isEqualToString:kName_Speaker] || [elementName isEqualToString:kName_Text]) {
[currentChatInfo setObject:[NSString stringWithString:currentString] forKey:elementName];
//把字符串添加进字典
}
storingCharacters = NO;//关闭解析
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if (storingCharacters) [currentString appendString:string];
//把解析出来的字符串添加到实例变量字符串
}
- (void)viewDidLoad {
[super viewDidLoad];
NSString *path=[[NSBundle mainBundle] pathForResource:@"chatLog" ofType:@"xml"];
currentString = [[NSMutableString alloc] initWithCapacity:0];
currentChatInfo = [[NSMutableDictionary alloc] initWithCapacity:2];
chatArray = [[NSMutableArray alloc] initWithCapacity:0];
[NSThread detachNewThreadSelector:@selector(loadThread:) toTarget:self withObject:path];//在这⾥新开了⼀个线程去加载⽂件,⼀般加载⽂件或下载都采⽤多线程的⽅式
}
- (void) finshLoadFile {
UITableView *tableView = (UITableView *)table;
[tableView reloadData];
}
- (void) loadThread:(NSString *)xmlFile {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSXMLParser *chatLogParser = [[NSXMLParser alloc] initWithContentsOfURL:[NSURL fileURLWithPath:xmlFile]];
[chatLogParser setDelegate:self];//千万别忘了设置代理
[currentString setString:@""];
[currentChatInfo removeAllObjects];
[chatLogParser parse];
[chatLogParser release];
[self performSelectorOnMainThread:@selector(finshLoadFile) withObject:nil waitUntilDone:YES];
[pool release];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [chatArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
cell.backgroundColor = [UIColor colorWithRed:0.859f green:0.886f blue:0.929f alpha:1.0f];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
NSDictionary *chatInfo = [chatArray objectAtIndex:[indexPath row]];
< = [chatInfo objectForKey:@"text"];
= [chatInfo objectForKey:@"speaker"];
return cell;
}
- (void)dealloc {
[currentString release];
[currentChatInfo release];
[chatArray release];
[super dealloc];
}
@end
说明⼀下,其实解析⽤到的函数只有三个,分别是
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *) qualifiedName attributes:(NSDictionary *)attributeDict; - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName;
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string;
他们的作⽤分别是开始解析元素,结束解析元素和得到元素。
⾄于具体的解析步骤在代码中有说明,⼀般都是按照这⼏个步骤来的。
在ViewDidLoad中,[NSThread detachNewThreadSelector:@selector(loadThread:) toTarget:self withObject:path];
开启⼀个线程去调⽤loadThread:⽅法,⽽在loadThread中初始化⼀个NSXMLParser的对象开始解析。
[self performSelectorOnMainThread:@selector(finshLoadFile) withObject:nil waitUntilDone:YES]这个
⽅法是更新主线程的界⾯的⽅法,因为在⼦线程内⽆法更新主线程的视图(规定),所以要在⼦线程中调⽤这个⽅法去更新主线程的界⾯。
之后加载到表格的⽅法就不⽤多说了吧很简单,这个框架也适合做在⼦线程⾥下载图⽚等等⼯作,更换loadThread⽅法就⾏了。
有问题积极留⾔啊,我不厌其烦地为⼤家解决!

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。