网络数据解析

XML文件写法

//根节点
  //开始标签
    
      //"CEO"节点属性
       //节点属性
        hmx
        23
        160
      
        xiaoming
        24
        170
      
    
  

XML解析

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

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

SAX一般分为5步
1.开始解析
- (void)parserDidStartDocument:(NSXMLParser *)parser;
2.开始解析标签
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)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 
@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 *)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;
}

你可能感兴趣的:(网络数据解析)