今天看了下苹果xml 解析,写了个小demo 心想还是 在博客上写点东西吧,毕竟很久很久都没有上来了
先上个效果图把
接下来 看下 工程目录图吧
本demo 分两种解析模式,一是苹果自带的, 首先先看下苹果自带的吧,工程文件为 NoteXMLParser 文件 ,另一种解析模式 是 NotesTBXMLParser文件
NoteXMLParser.h 文件代码如下 :
//
// NoteXMLParser.h
// TestXML
//
// Created by choni on 14-5-16.
// Copyright (c) 2014年 choni. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface NoteXMLParser : NSObject<NSXMLParserDelegate>
//解析出得数据,内部是字典类型
@property (strong,nonatomic) NSMutableArray * notes ;
// 当前标签的名字 ,currentTagName 用于存储正在解析的元素名
@property (strong ,nonatomic) NSString * currentTagName ;
//开始解析
- (void) start ;
@end
NoteXMLParser.m 文件代码如下:
//
// NoteXMLParser.m
// TestXML
//
// Created by choni on 14-5-16.
// Copyright (c) 2014年 choni. All rights reserved.
//
#import "NoteXMLParser.h"
@implementation NoteXMLParser
// 开始解析
-(void)start{
NSString * path = [[NSBundle mainBundle] pathForResource:@"Notes" ofType:@"xml"];
NSURL * url = [NSURL fileURLWithPath:path];
//开始解析 xml
NSXMLParser * parser = [[NSXMLParser alloc] initWithContentsOfURL:url];
parser.delegate = self ;
[parser parse];
NSLog(@"解析搞定...");
}
//文档开始时触发 ,开始解析时 只触发一次
-(void)parserDidStartDocument:(NSXMLParser *)parser{
_notes = [NSMutableArray new];
}
// 文档出错时触发
-(void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError{
NSLog(@"%@",parseError);
}
//遇到一个开始标签触发
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
//把elementName 赋值给 成员变量 currentTagName
_currentTagName = elementName ;
//如果名字 是Note就取出 id
if ([_currentTagName isEqualToString:@"Note"]) {
NSString * _id = [attributeDict objectForKey:@"id"];
// 实例化一个可变的字典对象,用于存放
NSMutableDictionary *dict = [NSMutableDictionary new];
//把id 放入字典中
[dict setObject:_id forKey:@"id"];
// 把可变字典 放入到 可变数组集合_notes 变量中
[_notes addObject:dict];
}
}
#pragma mark 该方法主要是解析元素文本的主要场所,由于换行符和回车符等特殊字符也会触发该方法,因此要判断并剔除换行符和回车符
// 遇到字符串时 触发
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
//替换回车符 和空格,其中 stringByTrimmingCharactersInSet 是剔除字符的方法,[NSCharacterSet whitespaceAndNewlineCharacterSet]指定字符集为换行符和回车符;
string = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if ([string isEqualToString:@""]) {
return;
}
NSMutableDictionary * dict = [_notes lastObject];
if ([_currentTagName isEqualToString:@"CDate"] && dict) {
[dict setObject:string forKey:@"CDate"];
}
if ([_currentTagName isEqualToString:@"Content"] && dict) {
[dict setObject:string forKey:@"Content"];
}
if ([_currentTagName isEqualToString:@"UserID"] && dict) {
[dict setObject:string forKey:@"UserID"];
}
}
//遇到结束标签触发
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
self.currentTagName = nil ;
//该方法主要是用来 清理刚刚解析完成的元素产生的影响,以便于不影响接下来解析
}
// 遇到文档结束时触发
-(void)parserDidEndDocument:(NSXMLParser *)parser{
[[NSNotificationCenter defaultCenter] postNotificationName:@"reloadViewNotification" object:self.notes userInfo:nil];
//进入该方法就意味着解析完成,需要清理一些成员变量,同时要将数据返回给表示层(表示图控制器) 通过广播机制将数据通过广播通知投送到 表示层
self.notes = nil;
}
@end
工程的控制器名称为:chonViewController
chonViewController.h文件代码如下:
//
// chonViewController.h
// TestXML
//
// Created by choni on 14-5-16.
// Copyright (c) 2014年 choni. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface chonViewController : UITableViewController
// 保存数据列表
@property (nonatomic,strong) NSMutableArray *listdata ;
@end
chonViewController.m文件代码如下:
//
// chonViewController.m
// TestXML
//
// Created by choni on 14-5-16.
// Copyright (c) 2014年 choni. All rights reserved.
//
#import "chonViewController.h"
#import "NotesTBXMLParser.h"
#import "NoteXMLParser.h"
@interface chonViewController ()
@end
@implementation chonViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.leftBarButtonItem = self.editButtonItem;
[[NSNotificationCenter defaultCenter ] addObserver:self selector:@selector(reloadView:) name:@"reloadViewNotification" object:nil];
//TBXMLParser 解析
// NotesTBXMLParser *parser = [NotesTBXMLParser new];
// // 开始解析
// [parser start];
// NSLog(@"viewDidLoad");
// 苹果自带解析
NoteXMLParser * parser = [NoteXMLParser new];
//开始解析
[parser start];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.listdata.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
NSMutableDictionary* dict = self.listdata[indexPath.row];
cell.textLabel.text = [dict objectForKey:@"Content"];
cell.detailTextLabel.text = [dict objectForKey:@"CDate"];
return cell;
}
#pragma mark - 处理通知
-(void)reloadView:(NSNotification*)notification
{
NSMutableArray *resList = [notification object];
self.listdata = resList;
[self.tableView reloadData];
}
@end
故事版图如下:
截止到这里 已经完成了 用苹果自带的解析器解析xml完毕了, 代码中得注释写的很详细!
接下来 看下 TBXMLParser解析模式
NotesTBXMLParser.h文件代码如下
//
// NotesTBXMLParser.h
// TestXML
//
// Created by choni on 14-5-16.
// Copyright (c) 2014年 choni. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface NotesTBXMLParser : NSObject
//解析出的数据内部是字典类型
@property (strong ,nonatomic) NSMutableArray * notes;
// 开始解析
-(void) start ;
@end
NotesTBXMLParser.m文件代码如下:
//
// NotesTBXMLParser.m
// TestXML
//
// Created by choni on 14-5-16.
// Copyright (c) 2014年 choni. All rights reserved.
//
#import "NotesTBXMLParser.h"
#import "TBXML.h"
@implementation NotesTBXMLParser
//开始解析
-(void)start
{
_notes = [NSMutableArray new];
TBXML* tbxml = [[TBXML alloc] initWithXMLFile:@"Notes.xml" error:nil];
TBXMLElement * root = tbxml.rootXMLElement;
// if root element is valid
if (root) {
TBXMLElement * noteElement = [TBXML childElementNamed:@"Note" parentElement:root];
while ( noteElement != nil) {
NSMutableDictionary *dict = [NSMutableDictionary new];
TBXMLElement *CDateElement = [TBXML childElementNamed:@"CDate" parentElement:noteElement];
if ( CDateElement != nil) {
NSString *CDate = [TBXML textForElement:CDateElement];
NSLog(@"CDate == %@",CDate);
[dict setValue:CDate forKey:@"CDate"];
}
TBXMLElement *ContentElement = [TBXML childElementNamed:@"Content" parentElement:noteElement];
if ( ContentElement != nil) {
NSString *Content = [TBXML textForElement:ContentElement];
[dict setValue:Content forKey:@"Content"];
}
TBXMLElement *UserIDElement = [TBXML childElementNamed:@"UserID" parentElement:noteElement];
if ( UserIDElement != nil) {
NSString *UserID = [TBXML textForElement:UserIDElement];
[dict setValue:UserID forKey:@"UserID"];
}
//获得ID属性
NSString *_id = [TBXML valueOfAttributeNamed:@"id" forElement:noteElement error:nil];
[dict setValue:_id forKey:@"id"];
[_notes addObject:dict];
noteElement = [TBXML nextSiblingNamed:@"Note" searchFromElement:noteElement];
}
}
NSLog(@"解析完成...");
[[NSNotificationCenter defaultCenter] postNotificationName:@"reloadViewNotification" object:self.notes userInfo:nil];
self.notes = nil;
}
@end
OK 搞定, 最后在 chonVIewController.m 文件中得 viewLoad方法中调用就好了 !
最后声明 :
TBXML解析xml 文档采用的是 DOM解析模式,通过上面的比较,发现他是非常好的解析框架,速度是所有xml中最快的 ,下面简单的介绍下如何使用
1.首先要到技术支持网站: http://www.tbxml.co.uk/TBXML/TBXML_Free.html 下载,下载完成后解压 出 TBXML-Headers 和TBXML-Code文件 并添加到工程
2.该框架不支持ARC 因此在使用该框架运行时 会报ARC 错误,这里就不吧 异常错误贴出来了 ,只提供解决的方法,需要修改工程目录中 TestXML-Prefix.pch 这个文件 ,在这个文件里 加上宏:如下图
#define ARC_ENABLED
3.由于TBXML依赖libz.dylib 库,还需要在工程中Framework中添加这个库,具体的添加方法 在这里就不说了, 完成以上3个步骤 在进行编译就可以啦!
今天先把xml 代码贴出来了,后续还有json数据解析,下午如果有空的话,搞个demo 在弄上来吧,希望对有得人有所帮助,因为我是新手,哈哈!刚学,献丑咯!
对了,xml文件内容如下":
viewDidLoad