NSXMLParser读取XML文件并将数据显示到TableView上
2016-06-18 17:32
501 查看
关于XML,有两种解析方式,分别是SAX(Simple API for XML,基于事件驱动的解析方式,逐行解析数据,采用协议回调机制)和DOM(Document Object Model ,文档对象模型。解析时需要将XML文件整体读入,并且将XML结构化成树状,使用时再通过树状结构读取相关数据,查找特定节点,然后对节点进行读或写)。苹果官方原生的NSXMLParse类库采用第一种方式,即SAX方式解析XML,它基于事件通知的模式,一边读取文档一边解析数据,不用等待文档全部读入以后再解析,所以如果你正打印解析的数据,而解析过程中间出现了错误,那么在错误节点之间的数据会正常打印,错误后面的数据不会被打印。解析过程由NSXMLParserDelegate协议方法回调。
首先先创建一个xml文件就叫做xml.xml吧:
接首创建一个相对应的M
接着添加一个自定义UITableViewCell类就让它叫做CustomTableViewCell.m吧,下一步将用到,代码如下:
在storyboard内添加一个ViewController并加一个TableView并设置好相应的约束条件后添加一个继承自UIViewController的类估且就叫做XmlToTableViewController,并设置上一步在storyboard添加的ViewController的Customer Class为XmlToTableViewController。
XmlToTableViewController要实现NSXMLParserDelegate这个接口,并选择相应要实现的方法。
最终的效果:
首先先创建一个xml文件就叫做xml.xml吧:
<?xml version="1.0" encoding="UTF-8"?> <Root> <Student> <pid>1</pid> <name>Jack</name> <sex>Male</sex> <age>18</age> </Student> <Student> <pid>2</pid> <name>Jodan</name> <sex>Male</sex> <age>19</age> </Student> <Student> <pid>3</pid> <name>Mily</name> <sex>Female</sex> <age>18</age> </Student> <Student> <pid>4</pid> <name>Rena</name> <sex>Female</sex> <age>20</age> </Student> <Student> <pid>5</pid> <name>Amy</name> <sex>Female</sex> <age>22</age> </Student> <Student> <pid>6</pid> <name>Teresa</name> <sex>Female</sex> <age>20</age> </Student> </Root>
接首创建一个相对应的M
//Person.h #import <Foundation/Foundation.h> @interface Person : NSObject @property (nonatomic,copy) NSString *pid; @property (nonatomic,copy) NSString *name; @property (nonatomic,copy) NSString *sex; @property (nonatomic,copy) NSString *age; @end //Person.m #import "Person.h" @implementation Person @synthesize pid,name,age,sex; @end
接着添加一个自定义UITableViewCell类就让它叫做CustomTableViewCell.m吧,下一步将用到,代码如下:
//CustomTableViewCell.h #import <UIKit/UIKit.h> @interface CustomTableViewCell : UITableViewCell @property UILabel *lblName; @property UILabel *lblSex; @property UILabel *lblAge; @end //CustomTableViewCell.m #import "CustomTableViewCell.h" @implementation CustomTableViewCell @synthesize lblAge,lblName,lblSex; - (void)awakeFromNib { // Initialization code } - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { UILabel *titleOfNameLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 60, 20)]; titleOfNameLabel.text = @"姓名:"; UILabel *titleOfAgeLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 40, 60, 20)]; titleOfAgeLabel.text = @"年龄:"; UILabel *titleOfSexLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 70, 60, 20)]; titleOfSexLabel.text = @"性别:"; //titleOfNameLabel.backgroundColor = [UIColor blackColor]; [self addSubview:titleOfNameLabel]; [self addSubview:titleOfAgeLabel]; [self addSubview:titleOfSexLabel]; lblName = [[UILabel alloc] initWithFrame:CGRectMake(80, 10, 100, 20)]; lblAge = [[UILabel alloc] initWithFrame:CGRectMake(80, 40, 100, 20)]; lblSex = [[UILabel alloc] initWithFrame:CGRectMake(80, 70, 100, 20)]; [self addSubview:lblName]; [self addSubview:lblAge]; [self addSubview:lblSex]; } return self; } - (void)setSelected:(BOOL)selected animated:(BOOL)animated { [super setSelected:selected animated:animated]; // Configure the view for the selected state } @end
在storyboard内添加一个ViewController并加一个TableView并设置好相应的约束条件后添加一个继承自UIViewController的类估且就叫做XmlToTableViewController,并设置上一步在storyboard添加的ViewController的Customer Class为XmlToTableViewController。
XmlToTableViewController要实现NSXMLParserDelegate这个接口,并选择相应要实现的方法。
//XmlToTableViewController.h #import "ViewController.h" #import "Person.h" @interface XmlToTableViewController : ViewController @property (weak, nonatomic) IBOutlet UITableView *tableView; @property (nonatomic,strong) NSXMLParser *parser; @property (nonatomic,strong) NSMutableArray *personArray; @property (nonatomic,copy) NSString *currentElement; @property (nonatomic,strong) Person *person; @end //XmlToTableViewController.m #import "XmlToTableViewController.h" #import "CustomTableViewCell.h" @interface XmlToTableViewController () <UITableViewDataSource,UITableViewDelegate,NSXMLParserDelegate> @end @implementation XmlToTableViewController - (void)viewDidLoad { [super viewDidLoad]; dispatch_queue_t q1 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_async(q1, ^{ }); NSBundle *bundle = [NSBundle mainBundle]; NSString *path = [bundle pathForResource:@"xml" ofType:@"xml"]; NSData *data = [NSData dataWithContentsOfFile:path]; self.parser = [[NSXMLParser alloc] initWithData:data]; //添加代理 self.parser.delegate = self; self.personArray = [NSMutableArray arrayWithCapacity:5]; [self.parser parse]; self.tableView.delegate = self; self.tableView.dataSource = self; } //几个代理方法的实现,是按逻辑上的顺序排列的,但实际调用过程中中间三个可能因为循环等问题乱掉顺序 //开始解析 - (void)parserDidStartDocument:(NSXMLParser *)parser { NSLog(@"parserDidStartDocument"); } -(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict { self.currentElement = elementName; if([self.currentElement isEqualToString:@"Student"]) { self.person = [[Person alloc] init]; } } //获取节点内容 -(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { if ([self.currentElement isEqualToString:@"pid"]) { [self.person setPid:string]; } else if([self.currentElement isEqualToString:@"name"]) { [self.person setName:string]; } else if([self.currentElement isEqualToString:@"sex"]) { [self.person setSex:string]; } else if([self.currentElement isEqualToString:@"age"]) { [self.person setAge:string]; } } //当一个节点读取完成后 -(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { if([elementName isEqualToString:@"Student"]) { [self.personArray addObject:self.person]; } self.currentElement = nil; } //完成XML文件的读取 -(void)parserDidEndDocument:(NSXMLParser *)parser { NSLog(@"parserDidEndDocument"); NSLog(@"Student's count is %lu",(unsigned long)[self.personArray count]); [self.tableView reloadData]; } //MARK:TABLEVIEW - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [self.personArray count]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSString *idenfifier = @"Cell"; //PersoUITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:idenfifier]; CustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:idenfifier]; if (cell == nil) { //用xib文件先画好 /*cell = [[[NSBundle mainBundle] loadNibNamed:@"PersonUITableViewCell" owner:nil options:nil] firstObject]; Person *currentPerson = [self.personArray objectAtIndex:indexPath.row]; if (currentPerson) { cell.lblName.text = currentPerson.name; cell.lblAge.text = currentPerson.age; cell.lblId.text = currentPerson.pid; cell.lblSex.text = currentPerson.sex; }*/ cell = [[CustomTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:idenfifier]; [tableView registerClass:[CustomTableViewCell class] forCellReuseIdentifier:idenfifier]; } Person *currentPerson = [self.personArray objectAtIndex:indexPath.row]; if (currentPerson) { cell.lblName.text = currentPerson.name; cell.lblAge.text = currentPerson.age; cell.lblSex.text = currentPerson.sex; } return cell; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return 126; }
最终的效果:
相关文章推荐
- 使用Masonry蹦到布局崩到 NSAssert(NO, @"attempting to add unsupported attribute: %@", secondViewAttribute);
- 观察者模式 详解
- jQuery基础--样式篇(2)
- PHP访问Oracle数据库
- lucene源码地址
- Matlab从日文转换成英文或中文转换成英文
- c#从大图截取一部分图片
- html5平板游戏列表
- Android自定义Dialog,实现长按ListView删除当中item数据
- Linux PC和ARM版的QT环境设置及到ARM移植&常见错误解决方法
- 基于TCP的Socket 编程
- 对C++虚函数、虚函数表的简单理解
- c/c++字符串处理大集合
- 项目相关错误系列之maven项目启动报错
- Android 中版本号的设置
- 67. Add Binary [easy] (Python)
- 中断处理流程深度剖析
- 常见的作业调度和进程调度算法总结
- 状态模式(State) Java 调用者不需要关心自身状态
- 找出一个字符串中第一个只出现一次的字符