JSON解析和XML解析

<span style="font-size:18px;">#import "RootViewController.h"
#import "Person.h"
#import "GDataXMLNode.h"
#import "JSONKit.h"

@interface RootViewController ()<NSXMLParserDelegate>

@property (nonatomic, retain) NSMutableArray *arr;//存储person对象
@property (nonatomic, retain) Person *per;//用来存储信息
@property (nonatomic, copy) NSString *str;//存储读取到的字符串

@end</span><pre name="code" class="objc"><span style="font-size:18px;">- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.view.backgroundColor = [UIColor whiteColor];
    UILabel *XMLLabel = [[UILabel alloc] initWithFrame:CGRectMake(110, 30, 100, 30)];
    XMLLabel.text = @"XML解析";
    XMLLabel.textAlignment = NSTextAlignmentCenter;
    [self.view addSubview:XMLLabel];
    [XMLLabel release];
    
    UILabel *JSONLabel = [[UILabel alloc] initWithFrame:CGRectMake(110, 200, 100, 30)];
    JSONLabel.text = @"JSON解析";
    JSONLabel.textAlignment = NSTextAlignmentCenter;
    [self.view addSubview:JSONLabel];
    [JSONLabel release];
    
    NSArray *titles = @[@"SAX解析",@"Dom解析第一种方式",@"Dom解析第二种方式",@"系统解析",@"字符串解析",@"数组解析",@"字典解析",@"Data解析"];
    NSArray *methods = @[@"handleSAX:",@"handleDomBtn1:",@"handleDomBtn2:",@"handleSystemJSON:",@"handleStrBtn:",@"handleArrBtn:",@"handleDicBtn:",@"handleDataBtn:"];
    CGFloat height = 70;
    for (int i = 0; i < 8; i++) {
        UIButton *SAXBtn = [UIButton buttonWithType:UIButtonTypeSystem];
        SAXBtn.frame = CGRectMake(60, height, 200, 30);
        SAXBtn.backgroundColor = [UIColor greenColor];
        [SAXBtn setTitle:titles[i] forState:UIControlStateNormal];
        
        //根据字符串初始化方法
        SEL selector = NSSelectorFromString(methods[i]);
        
        [SAXBtn addTarget:self action:selector forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:SAXBtn];
        if (i == 2) {
            height = 200;
        }
        height += 40;
    }
    UILabel *text = [[UILabel alloc] initWithFrame:CGRectMake(110, 470, 100, 30)];
    text.text = @"加油!";
    text.textAlignment = NSTextAlignmentCenter;
    [self.view addSubview:text];
    [text release];
}
/**
 * 解析:按照一种约定好的格式(假象),由后台开发人员按照格式存数据,由前端开发人员按照格式取数据。
    谨记:这种格式是由后台开发人员决定的,我们无权决定
    解析本质:按照约定好的格式,取出我们想要的数据的过程。
    当今比较流行的格式:XML格式 和 JSON格式
    XMlL解析两种解析原理:
    SAX解析:是一种基于事件回调的解析机制,就是使用协议以及代理。SAX解析就是逐行解析,读入数据时只读入一行,一行一行解析,所以SAX解析占用内存较小,较适合大数据解析
    DOM解析:一次性将内容全部读入内存,将内容读成一个树形结构,逐层解析,适合小数据解析
 *
 */

//SAX解析
- (void)handleSAX:(UIButton *)btn
{
    //1.先获取解析的文件路径(包里)
    NSString *xmlPath = [[NSBundle mainBundle] pathForResource:@"Person" ofType:@"xml"];
    //2.根据文件路径初始化NSData对象
    NSData *data = [NSData dataWithContentsOfFile:xmlPath];
    //3.创建解析工具对象
    NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
    //4.设置代理
    parser.delegate = self;
    //5.开始解析
    [parser parse];
}
#pragma mark - NSXMLParserDelegate

//当读取到开始标签时触发
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
    //NSLog(@"start %@", attributeDict);
    //当数据存储到开始标签的属性中时,处理方式
    if ([elementName isEqualToString:@"Persons"]) {
        //为数组开辟空间
        self.arr = [NSMutableArray array];
        
    } else if ([elementName isEqualToString:@"person"]) {
        //为person开辟空间
        self.per = [[[Person alloc] init] autorelease];
        //self.per = [[Person alloc] init];
        //[_per release];
        [self.arr addObject:self.per];
    } else if ([elementName isEqualToString:@"name"]) {
        self.per.name = attributeDict[@"name"];
    } else if ([elementName isEqualToString:@"gender"]) {
        self.per.gender = attributeDict[@"gender"];
    } else if ([elementName isEqualToString:@"age"]) {
        self.per.age = attributeDict[@"age"];
    } else if ([elementName isEqualToString:@"phoneNumber"]) {
        self.per.phoneNumber = attributeDict[@"phoneNumber"];
    } else if ([elementName isEqualToString:@"imageName"]) {
        self.per.imageName = attributeDict[@"imageName"];
    }
    
    
    //当数据存储在开始标签和结束标签之间时
//    if ([elementName isEqualToString:@"Persons"]) {
//        //为数组开辟空间
//        self.arr = [NSMutableArray array];
//    } else if ([elementName isEqualToString:@"person"]) {
//        //为person对象开辟空间
//        self.per = [[[Person alloc] init] autorelease];
//    }
    
}
//当读到标签后的内容时触发
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
   // NSLog(@"content %@", string);
    //self.str = string;//保存读取到的数据
}
//当读取到结束标签时触发
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    //NSLog(@"end %@", elementName);
//    if ([elementName isEqualToString:@"name"]) {
//        self.per.name = self.str;
//    } else if ([elementName isEqualToString:@"gender"]) {
//        self.per.gender = self.str;
//    } else if ([elementName isEqualToString:@"age"]) {
//        self.per.age = self.str;
//    } else if ([elementName isEqualToString:@"phoneNumber"]) {
//        self.per.phoneNumber = self.str;
//    } else if ([elementName isEqualToString:@"imageName"]) {
//        self.per.imageName = self.str;
//    } else if ([elementName isEqualToString:@"person"]) {
//        //当读到person结束标签时,person对象已经赋值完毕,存储到数组中
//        [self.arr addObject:self.per];
//    }
}

//当解析完毕之后触发
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
    //NSLog(@"%@", self.arr);
    
}
//DOM解析第一种方式
/**
 * DOM解析使用Google提供的一个开源高效的XML解析工具GDataXMLNode,他的效果要比NSXMLParser要快10倍
    使用方式:
    1:先倒入系统动态链接库 libxml2.2.dylib(在buli phrase中的link下点击加号,弹出来一个输入框,填入libxml2.2.dylib)
 
    2:在bulidSettings中的Header Search Path中添加/usr/include/libxml2
    3:在bulidSettings中的Other Linker Flags contain中添加 -lxml2
 */
- (void)handleDomBtn1:(UIButton *)btn
{
    //1.先获取解析文件路径
    NSString *xmlPath = [[NSBundle mainBundle] pathForResource:@"Person" ofType:@"xml"];
    //2.初始化xml字符串
    NSString *xmlStr = [NSString stringWithContentsOfFile:xmlPath encoding:NSUTF8StringEncoding error:nil];
    //3.初始化一个GDataXMLDocument对象,因为解析时所有的内容都是从该对象中读取(所以需要将要解析的内容放入该对象中)
    GDataXMLDocument *document = [[GDataXMLDocument alloc] initWithXMLString:xmlStr options:0 error:nil];
    //4.获取根节点(GDataXMLElement对象)
    GDataXMLElement *rootElement = [document rootElement];
    //5.获取根节点的所有子节点
    NSArray *personElements = [rootElement elementsForName:@"person"];
    //6.遍历数组,得到每一个person节点,然后再得到person节点下的子节点
    for (GDataXMLElement *element in personElements) {
        //获取person节点下的name节点
        GDataXMLElement *nameElement = [[element elementsForName:@"name"] firstObject];
        //获取person节点下的gender节点
        GDataXMLElement *genderElement = [[element elementsForName:@"gender"] firstObject];
        //获取person节点下的age节点
        GDataXMLElement *ageElement = [[element elementsForName:@"age"] firstObject];
        //获取person节点下的phonenumber节点
        GDataXMLElement *phoneNumberElement = [[element elementsForName:@"phoneNumber"] firstObject];
        //获取person节点下的imagename节点
        GDataXMLElement *imageElement = [[element elementsForName:@"imageName"] firstObject];
        //1.获取开始标签和结束标签中的值
//        NSString *name = [nameElement stringValue];
//        NSString *gender = [genderElement stringValue];
//        NSString *age = [ageElement stringValue];
//        NSString *phoneNumber = [phoneNumberElement stringValue];
//        NSString *imageName = [imageElement stringValue];
//        NSLog(@"%@,%@,%@,%@,%@", name, gender, age, phoneNumber, imageName);
        //2.获取标签中属性中存储的数据
        //属性对应的类 GDataXMLNode
        GDataXMLNode *nameNode = [nameElement attributeForName:@"name"];
        GDataXMLNode *genderNode = [genderElement attributeForName:@"gender"];
        GDataXMLNode *ageNode = [ageElement attributeForName:@"age"];
        GDataXMLNode *phoneNumberNode = [phoneNumberElement attributeForName:@"phoneNumber"];
        GDataXMLNode *imageNameNode = [imageElement attributeForName:@"imageName"];
        NSString *name = [nameNode stringValue];
        NSString *gender = [genderNode stringValue];
        NSString *age = [ageNode stringValue];
        NSString *phoneNumber = [phoneNumberNode stringValue];
        NSString *imageName = [imageNameNode stringValue];
        NSLog(@"%@,%@,%@,%@,%@", name, gender, age, phoneNumber, imageName);
    }
    
}

- (void)handleDomBtn2:(UIButton *)btn
{
    //NSLog(@"%s", __FUNCTION__);
    //1.先获取解析文件路径
    NSString *xmlPath = [[NSBundle mainBundle] pathForResource:@"Person" ofType:@"xml"];
    //2.初始化xml字符串
    NSString *xmlStr = [NSString stringWithContentsOfFile:xmlPath encoding:NSUTF8StringEncoding error:nil];
    //3.初始化一个GDataXMLDocument对象,因为解析时所有的内容都是从该对象中读取(所以需要将要解析的内容放入该对象中)
    GDataXMLDocument *document = [[GDataXMLDocument alloc] initWithXMLString:xmlStr options:0 error:nil];
    /**
     *  XPath 只要给定相对的路径即可,比如://name, 只要能达到name,都可以把name获取到
        绝对路径为单斜杠,相对路径为双斜杠
     */
    //4.获取所有的name节点
    NSArray *nameElements = [document nodesForXPath:@"//name" error:nil];
    //获取所有的gender节点
    NSArray *genderElements = [document nodesForXPath:@"//gender" error:nil];
    //获取所有的age节点
    NSArray *ageElements= [document nodesForXPath:@"//age" error:nil];
    //获取所有的phoneNumber节点
    NSArray *phoneNumberElements = [document nodesForXPath:@"//phoneNumber" error:nil];
    //获取所有的imageName节点
    NSArray *imageNameElements = [document nodesForXPath:@"//imageName" error:nil];
    //通过循环取出每个节点
    for (int i = 0; i < 3; i++) {
        GDataXMLElement *nameEle = nameElements[i];
        GDataXMLElement *genderEle = genderElements[i];
        GDataXMLElement *ageEle = ageElements[i];
        GDataXMLElement *phoneEle = phoneNumberElements[i];
        GDataXMLElement *imageEle = imageNameElements[i];
        NSString *name = [nameEle stringValue];
        NSString *gender = [genderEle stringValue];
        NSString *age = [ageEle stringValue];
        NSString *phoneNumber = [phoneEle stringValue];
        NSString *imageName = [imageEle stringValue];
        NSLog(@"%@,%@,%@,%@,%@", name, gender, age, phoneNumber, imageName);
    }

}

- (void)handleSystemJSON:(UIButton *)btn
{
    //1.获取文件路径
    NSString *jsonPath = [[NSBundle mainBundle] pathForResource:@"Student" ofType:@"json"];
    //初始化NSData对象
    NSData *data = [NSData dataWithContentsOfFile:jsonPath];
    //3.解析
    //MutableContainers 读成一个可变的容器(数组,字典,集合)
    NSMutableArray *arr = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
    NSLog(@"%@", arr);
    
}
/**
 *  对于jsonkit 提供的解析方式,是为nsstring, nsdata添加分类的方式,在分类中添加了解析的方式,效率仅次于系统的
    将json格式数据解析成nsarray, nsdictionary,
    而为nsarray,nsdictionary添加的分类的方法,则是将oc的对象,转化为json格式字符串
 */
//jsonkit
- (void)handleStrBtn:(UIButton *)btn
{
    //1.获取文件路径
    NSString *jsonPath = [[NSBundle mainBundle] pathForResource:@"Student" ofType:@"json"];
    //2.初始化NSString对象
    NSString *jsonStr = [NSString stringWithContentsOfFile:jsonPath encoding:NSUTF8StringEncoding error:nil];
    //3.解析
    NSArray *arr = [jsonStr objectFromJSONString];
    NSLog(@"%@", arr);
    
}

- (void)handleArrBtn:(UIButton *)btn
{
    //将oc的数组转化成json格式字符串
    NSArray *arr = @[@"aa",@"bb",@"vv",@"dd"];
    //转化
    NSString *jsonStr = [arr JSONString];
    NSLog(@"%@", jsonStr);
}

- (void)handleDicBtn:(UIButton *)btn
{
    NSDictionary *dic = @{@"name": @"frank",@"gender":@"man",@"age":@"19"};
    NSString *jsonDic = [dic JSONString];
    NSLog(@"%@", jsonDic);
}

- (void)handleDataBtn:(UIButton *)btn
{
    //1.获取文件路径
    NSString *jsonPath = [[NSBundle mainBundle] pathForResource:@"Student" ofType:@"json"];
    //2.初始化NSData对象
    NSData *data = [NSData dataWithContentsOfFile:jsonPath];
    //3.解析
    NSArray *arr = [data objectFromJSONData];
    NSLog(@"%@", arr);
    
}
</span>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值