xml解析

来源:互联网 发布:没有激素的护肤品知乎 编辑:程序博客网 时间:2024/05/20 16:09

在iOS开发中,数据解析通常有两种方式,一种是JSON解析,一种是XML解析。今天着重讲解一下XML文件解析的三种方式。


  • 解析下面这样一个XML文件

  • 点击下载:XML文件

准备工作

  • 首先创建一个Student模型
  • student.h
#import <Foundation/Foundation.h>@interface Student : NSObject@property (nonatomic, copy) NSString *name;@property (nonatomic, copy) NSString *gender;@property (nonatomic, copy) NSString *age;@property (nonatomic, copy) NSString *nickname;@end
  • student.m
#import "Student.h"@implementation Student- (void)setValue:(id)value forUndefinedKey:(NSString *)key {}@end
  • 重写setValue:forUndefinedKey防止程序crash

  • 在storyboard里拖两个button,名字分别为SAX和DOM
  • 关联点击事件,取名为saxAction和domAction

  • 导入头文件,签订协议,设置属性
#import "ViewController.h"#import "Student.h"#import "GDataXMLNode.h"#import "XMLReader.h"@interface ViewController ()<    NSXMLParserDelegate>@property (nonatomic, retain) NSMutableArray *studentArray;// 用来记录当前xml解析的节点名称@property (nonatomic, copy) NSString *currentElementName;@end

方式一:SAX解析

  • SAX解析的特点是逐行进行解释
#pragma mark - SAX解析// SAX 逐行解析- (IBAction)saxAction:(id)sender {    NSString *xmlFilePath = [[NSBundle mainBundle] pathForResource:@"Demo.xml" ofType:nil];    NSData *xmlData = [NSData dataWithContentsOfFile:xmlFilePath];    NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithData:xmlData];    xmlParser.delegate = self;    //  开始解析    [xmlParser parse];}# pragma mark - 协议方法// 开始- (void)parserDidStartDocument:(NSXMLParser *)parser {    NSLog(@"开始");    self.studentArray = [NSMutableArray array];}// 获取节点头- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict {    NSLog(@"start element : %@", elementName);    self.currentElementName = elementName;    if ([elementName isEqualToString:@"student"]) {        Student *stu = [[Student alloc] init];        [_studentArray addObject:stu];    }}// 获取节点的值 (这个方法在获取到节点头和节点尾后,会分别调用一次)- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {    NSLog(@"value : %@", string);    if (_currentElementName != nil) {        Student *stu = [_studentArray lastObject];        [stu setValue:string forKey:_currentElementName];    }}// 获取节点尾- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {    _currentElementName = nil;    NSLog(@"end element :%@", elementName);}// 结束- (void)parserDidEndDocument:(NSXMLParser *)parser {    NSLog(@"结束");    NSLog(@"%@",_studentArray);}

方式二:DOM解析

  • DOM解析的特点是通过节点解析
  • 使用第三方类库
  • 点击下载:GDataXMLNode
  • 当前工程使用的是ARC
  • 导入头文件后的准备工作

  • 第一步


  • 第二步


  • 第三步


  • 第四步

  • 复制下面这句话进去
    /usr/include/libxml2

  • 第五步

  • 复制下面这句话进去
    -fno-objc-arc

  • 代码
# pragma mark - DOM按节点解析- (IBAction)domAction:(id)sender {    self.studentArray = [NSMutableArray array];    NSString *xmlFilePath = [[NSBundle mainBundle] pathForResource:@"Demo.xml" ofType:nil];    NSData *xmlData = [NSData dataWithContentsOfFile:xmlFilePath];    NSError *error = nil;    GDataXMLDocument *xmlDocument = [[GDataXMLDocument alloc] initWithData:xmlData options:0 error:&error];    if (error) {        NSLog(@"error : %@", error);        return;    }    // 取根节点    GDataXMLElement *rootElement = [xmlDocument rootElement];    // 获取根节点下的所有子节点    NSArray *elementArray =  rootElement.children;    for (GDataXMLElement *studentElement in elementArray) {        Student *stu = [[Student alloc] init];        [_studentArray addObject:stu];        for (GDataXMLElement *attributeElement in studentElement.children) {            [stu setValue:attributeElement.stringValue forKey:attributeElement.name];        }    }    NSLog(@"array : %@", _studentArray);}@end

第三种方式:XMLReader解析

  • XMLReader通过向前读取文档并识别读取到的元素
  • 为我们提供了一种消耗资源最少的方式来解析XML数据
  • 点击下载:XMLReader
  • 下载完成后导入整个文件到项目里
- (void)viewDidLoad {    [super viewDidLoad];    NSString *xmlFileString = [[NSBundle mainBundle] pathForResource:@"Demo" ofType:@"xml"];    NSData *xmlData = [NSData dataWithContentsOfFile:xmlFileString];    NSError *error = nil;    if (error) {        NSLog(@"error : %@", error);    }    NSDictionary *result = [XMLReader dictionaryForXMLData:xmlData error:&error];    NSLog(@"result : %@", result);}
  • 通过XMLReader最后拿到的是一个字典


总结

  • XML优点
    • 格式统一,符合标准
    • 容易与其他系统进行远程交互,数据共享比较方便
  • XML的缺点
    • XML文件庞大,文件格式复杂,传输占带宽
    • 服务器端和客户端都需要花费大量代码来解析XML,导致服务器端和客户端代码变得异常复杂且不易维护
    • 客户端不同浏览器之间解析XML的方式不一致,需要重复编写很多代码
    • 服务器端和客户端解析XML花费较多的资源和时间


作者:PhelanGeek
链接:http://www.jianshu.com/p/0e158f522a01
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 微信记录全没了怎么办 微信记录没有了怎么办 ipad登录不了下不了软件怎么办 苹果手机打开自动时间不对怎么办 魅族手机时间不同步怎么办 小米手环时间不准怎么办 电脑网络dns配置错误怎么办 去泰国手机要打电话怎么办 苹果6s音量小怎么办 三星0n7充电慢怎么办 在国外接受不到验证码怎么办 ip地址错误网络无法连通怎么办 注册微信收不到验证码怎么办 安卓手机收不到短信怎么办 手机被短信验证码轰炸怎么办 美国访学一年手机卡怎么办方便 小狗吃了葡萄皮怎么办 ios迅雷下载不了的资源怎么办 ipad软件商店内容少怎么办? 脸摔伤后留下黑印怎么办 不确定孩子是不是老公的怎么办 孩子接种证丢了怎么办 孩子的出生证丢了怎么办 私秘边上肿了怎么办 书法作品少写一个字怎么办 炉石传说ios闪退怎么办 ck手表表链大了怎么办 天梭手表卡扣坏了怎么办 机械表平时不戴怎么办 天梭机械表慢了怎么办 手表每天慢10秒怎么办 浪琴机械表不走了怎么办 大提单号被修改了怎么办 入户中山没有三年居住证明怎么办 加拼关单号舱单信息没有怎么办 外贸中交货期晚了怎么办 履约保函到期了怎么办 续贷高校未通过怎么办 安卓手机网速慢怎么办 探探性别错了怎么办 尿酸高导致脚肿怎么办