网络数据解析

XML文件写法

<Classes>//根节点
  <Class1>//开始标签
    <Students>
      <Student position = "CEO">//"CEO"节点属性
       //节点属性
        <name>hmx</name>
        <age>23</age>
        <height>160</height>
      <Student>
        <name>xiaoming</name>
        <age>24</age>
        <height>170</height>
      </Student>
    </Students>
  </Class1>
</Classes>

XML解析

SAX:逐行解析(主类:NSXMLParser)

逐行解析顾名思义就是一行一行的读取解析,需要遵循代理<NSXMLParserDelegate>

SAX一般分为5步
1.开始解析
- (void)parserDidStartDocument:(NSXMLParser *)parser;
2.开始解析标签
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict;
3.标签对应的值
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string;
4.结束解析标签
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName;
5.结束解析
- (void)parserDidEndDocument:(NSXMLParser *)parser;
以上面的Student为例子

1.创建一个Student的model类

//Student的model类h文件
#import <Foundation/Foundation.h>
@interface Student : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) NSInteger age;
@property (nonatomic, assign) float height;
@end

2.定义一个全局变量数组用来存储解析后的数据,定义一个全局变量用来存储标签,因为我们要通过标签来判断数据

@property (nonatomic, strong) NSMutableArray *studentArray;
@property (nonatomic, strong) NSString *currentElementName;

3.这里使用一个UIbutton动作来进行解析,点击button就进行XML解析,UIButton创建不在多说

//点击按钮进行解析
- (IBAction)SAXDidTapAction:(UIButton *)sender {
    //获取文件绝对路径
    NSString *path = [[NSBundle mainBundle] pathForResource:@"student" ofType:@"txt"];
    //创建一个NSData
    NSData *data = [NSData dataWithContentsOfFile:path];
    //初始化XMLParser
    NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithData:data];
    
    xmlParser.delegate = self;
    [xmlParser parse];
}

4.遵循协议,重写方法,记得数组需要先初始化

//开始解析
- (void)parserDidStartDocument:(NSXMLParser *)parser {
    NSLog(@"DidStart");
}
//解析开始元素(标签)
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict {
    //记录当前elementName
    self.currentElementName = elementName;
//创建学生属性并添加到数组中
    if ([elementName isEqualToString:@"Student"]) {
        Student *student = [[Student alloc] init];
        [self.studentArray addObject:student];
    }
}
//每一个标签对应的值
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    //获取最后一个元素
    Student *stu = [self.studentArray lastObject];
    //KVC模式赋值,记得在Student类中重写方法
//- (void)setValue:(id)value forUndefinedKey:(NSString *)key;
    [stu setValue:string forKey:self.currentElementName];
}
//解析结束标签
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
 //这里设置为空的原因: foundCharacters方法在结束标签处会调用一次,
//不置为空会再次进入KVC赋值,Student内容会变为空或0
    self.currentElementName = @"";
}
//结束解析
- (void)parserDidEndDocument:(NSXMLParser *)parser {
    NSLog(@"DidEnd");
    for (Student *stu in self.studentArray) {
        NSLog(@"%@", stu);
    }
}

DOM解析:通过GDataXMLNode类进行解析,该类会将数据全部解析完毕,在使用前先做一些处理

1.将文件添加到工程(http://pan.baidu.com/s/1eSrvPgY)
2.在工程中添加动态库: libxml2.dylib
3.在工程的Build Settings中找到Header Search Path项 添加/usr/include/libxml2
4.将第三方库文件改为ARC MRC通用状态,找到Build Phases中的Compile Sources中的GDataXMLNode.m文件双击添加-fno-objc-arc

程序

  1. 初始化GDataXMLDocument
//data为路径,解析例子同SAX, data为SAX中的data
GDataXMLDocument *GDocument = [[GDataXMLDocument alloc] initWithData:data options:0 error:&error];
  1. 获取根节点
GDataXMLElement *rootElement = GDocument.rootElement;
  1. 获取子节点
for (GDataXMLElement *subElement in rootElement.children) {
        Student *stu = [[Student alloc] init];
        //找到student的子节点, 也就是name age height,然后赋值
        for (GDataXMLElement *contactElement in subElement.children) {
            [stu setValue:contactElement.stringValue forKey:contactElement.name];
        }
        [self.studentArray addObject:stu];
    }

通过XMLDictionary类进行解析

NSDictionary *dict = [NSDictionary dictionaryWithXMLData:data];
    
    NSArray *array = dict[@"Student"];
    
    for (NSDictionary *stuDict in array) {
        Student *stu = [[Student alloc] init];
        [stu setValuesForKeysWithDictionary:stuDict];
        
        [self.studentArray addObject:stu];
    }

上面的均为简单的例子,下面来看一个比较复杂的例子,这里使用XMLDictionary类进行解析: Cartoon.xml进行解析

这里我们只需要两个数据,name跟desc

  1. 创建Model类
    Model.h
@interface CartoonModel : NSObject

@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *desc;

@end

Model.m

#import "CartoonModel.h"

@implementation CartoonModel
//当没有找到key时会进入这个方法
- (void)setValue:(id)value forUndefinedKey:(NSString *)key {
    
}
@end
  1. 数据解析
//这里使用懒加载方法,cartoonArray为全局变量(NSMutableArray)
- (NSMutableArray *)cartoonArray {
    if (!_cartoonArray) {
        _cartoonArray = [[NSMutableArray alloc] init];
        //获取绝对路径
        NSString *path = [[NSBundle mainBundle] pathForResource:@"Cartoon" ofType:@"xml"];
        NSData *data = [NSData dataWithContentsOfFile:path];
        //使用方法dictionaryWithXMLData将数据转换为字典
        NSDictionary *dict = [NSDictionary dictionaryWithXMLData:data];
        //通过字典的key获取下级字典
        NSDictionary *resultDict = dict[@"results"];
        //通过数组接收数据
        NSArray *albumInfoDict = resultDict[@"AlbumInfo"];
        //通过model类接收数组内部的各个model数据
        for (NSDictionary *modelDict in albumInfoDict) {
            CartoonModel *model = [[CartoonModel alloc] init];
            //KVC模式赋值
            [model setValuesForKeysWithDictionary:modelDict];
            [_cartoonArray addObject:model];
        }
    }
    return _cartoonArray;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容