zoukankan      html  css  js  c++  java
  • 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>
            <speaker><![CDATA[other4]]></speaker>
            <text><![CDATA[world4]]></text>
        </chat>
        <chat>
            <speaker><![CDATA[other5]]></speaker>
            <text><![CDATA[world5]]></text>
        </chat>
        
    </chats>

    把它放在了一个叫chatLog.xml的文件中,再拖到工程里面来

    这个解析只需要一个类就够了,下面来看看头文件

    #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]];
        cell.textLabel.text = [chatInfo objectForKey:@"text"];
        cell.detailTextLabel.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方法就行了。
    有问题积极留言啊,我不厌其烦地为大家解决!
     
  • 相关阅读:
    HDU 1560 DNA sequence (迭代加深搜索)
    POJ-1077 HDU 1043 HDU 3567 Eight (BFS预处理+康拓展开)
    CSUST 1011 神秘群岛 (Dijkstra+LCA)
    LCA 倍增
    HDU 1003 Max Sum 求区间最大值 (尺取法)
    Codeforce 867 C. Ordering Pizza (思维题)
    POJ 3349 Snowflake Snow Snowflakes (Hash)
    POJ 2774 Long Long Message (Hash + 二分)
    POJ 1200 Crazy Search (Hash)
    前端面试总结(转)
  • 原文地址:https://www.cnblogs.com/xiaobaizhu/p/2790048.html
Copyright © 2011-2022 走看看