zoukankan      html  css  js  c++  java
  • NSXMLParser读取XML文件并将数据显示到TableView上

    关于XML,有两种解析方式,分别是SAX(Simple API for XML,基于事件驱动的解析方式,逐行解析数据,采用协议回调机制)和DOM(Document Object Model ,文档对象模型。解析时需要将XML文件整体读入,并且将XML结构化成树状,使用时再通过树状结构读取相关数据,查找特定节点,然后对节点进行读或写)。苹果官方原生的NSXMLParse类库采用第一种方式,即SAX方式解析XML,它基于事件通知的模式,一边读取文档一边解析数据,不用等待文档全部读入以后再解析,所以如果你正打印解析的数据,而解析过程中间出现了错误,那么在错误节点之间的数据会正常打印,错误后面的数据不会被打印。解析过程由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这个接口,并选择相应要实现的方法。

      1 //XmlToTableViewController.h
      2 #import "ViewController.h"
      3 #import "Person.h"
      4 
      5 @interface XmlToTableViewController : ViewController
      6 
      7 @property (weak, nonatomic) IBOutlet UITableView *tableView;
      8 
      9 @property (nonatomic,strong) NSXMLParser *parser;
     10 @property (nonatomic,strong) NSMutableArray *personArray;
     11 @property (nonatomic,copy) NSString *currentElement;
     12 @property (nonatomic,strong) Person *person;
     13 
     14 @end
     15 
     16 
     17 //XmlToTableViewController.m
     18 #import "XmlToTableViewController.h"
     19 #import "CustomTableViewCell.h"
     20 
     21 @interface XmlToTableViewController () <UITableViewDataSource,UITableViewDelegate,NSXMLParserDelegate>
     22 
     23 @end
     24 
     25 @implementation XmlToTableViewController
     26 
     27 - (void)viewDidLoad {
     28     [super viewDidLoad];
     29     
     30     dispatch_queue_t q1 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
     31     
     32     dispatch_async(q1, ^{
     33         
     34 
     35     });
     36     
     37     NSBundle *bundle = [NSBundle mainBundle];
     38     NSString *path = [bundle pathForResource:@"xml" ofType:@"xml"];
     39     NSData *data = [NSData dataWithContentsOfFile:path];
     40     self.parser = [[NSXMLParser alloc] initWithData:data];
     41     //添加代理
     42     self.parser.delegate = self;
     43     self.personArray = [NSMutableArray arrayWithCapacity:5];
     44     [self.parser parse];
     45     
     46     self.tableView.delegate = self;
     47     self.tableView.dataSource = self;
     48 }
     49 
     50 
     51 
     52 //几个代理方法的实现,是按逻辑上的顺序排列的,但实际调用过程中中间三个可能因为循环等问题乱掉顺序
     53 //开始解析
     54 - (void)parserDidStartDocument:(NSXMLParser *)parser {
     55     NSLog(@"parserDidStartDocument");
     56 }
     57 
     58 -(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict {
     59     self.currentElement = elementName;
     60     if([self.currentElement isEqualToString:@"Student"]) {
     61         self.person = [[Person alloc] init];
     62     }
     63 }
     64 
     65 //获取节点内容
     66 -(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
     67     if ([self.currentElement isEqualToString:@"pid"]) {
     68         [self.person setPid:string];
     69     } else if([self.currentElement isEqualToString:@"name"]) {
     70         [self.person setName:string];
     71     } else if([self.currentElement isEqualToString:@"sex"]) {
     72         [self.person setSex:string];
     73     } else if([self.currentElement isEqualToString:@"age"]) {
     74         [self.person setAge:string];
     75     }
     76 }
     77 
     78 //当一个节点读取完成后
     79 -(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
     80     if([elementName isEqualToString:@"Student"]) {
     81         [self.personArray addObject:self.person];
     82     }
     83     self.currentElement = nil;
     84 }
     85 
     86 //完成XML文件的读取
     87 -(void)parserDidEndDocument:(NSXMLParser *)parser {
     88     NSLog(@"parserDidEndDocument");
     89     NSLog(@"Student's count is %lu",(unsigned long)[self.personArray count]);
     90     [self.tableView reloadData];
     91 }
     92 
     93 
     94 //MARK:TABLEVIEW
     95 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
     96     return [self.personArray count];
     97 }
     98 
     99 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    100     NSString *idenfifier = @"Cell";
    101     //PersoUITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:idenfifier];
    102     CustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:idenfifier];
    103     if (cell == nil) {
    104         //用xib文件先画好
    105         /*cell = [[[NSBundle mainBundle] loadNibNamed:@"PersonUITableViewCell" owner:nil options:nil] firstObject];
    106         Person *currentPerson = [self.personArray objectAtIndex:indexPath.row];
    107         if (currentPerson) {
    108             cell.lblName.text = currentPerson.name;
    109             cell.lblAge.text = currentPerson.age;
    110             cell.lblId.text = currentPerson.pid;
    111             cell.lblSex.text = currentPerson.sex;
    112         }*/
    113         
    114         cell = [[CustomTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:idenfifier];
    115         
    116         [tableView registerClass:[CustomTableViewCell class] forCellReuseIdentifier:idenfifier];
    117     }
    118     Person *currentPerson = [self.personArray objectAtIndex:indexPath.row];
    119     if (currentPerson) {
    120         cell.lblName.text = currentPerson.name;
    121         cell.lblAge.text = currentPerson.age;
    122         cell.lblSex.text = currentPerson.sex;
    123     }
    124 
    125     return cell;
    126 }
    127 
    128 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    129     return 126;
    130 }

     最终的效果:

  • 相关阅读:
    项目管理
    智能硬件如何确定需求:场景约束
    产品设计
    产品设计之前,如何分析业务需求和用户痛点?
    微信小程序挑一挑辅助
    C#实现冲顶大会辅助工具(截图+图像识别+搜索)
    读取配置文件--AppConfig
    文件各种上传,离不开的表单
    使用C#委托来实现异步编程
    Table 组件构建过程中遇到的问题与解决思路
  • 原文地址:https://www.cnblogs.com/foxting/p/5596561.html
Copyright © 2011-2022 走看看