你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> iOS XML/JSON解析

iOS XML/JSON解析

編輯:IOS開發綜合
點擊打開下載鏈接iOS,XML/JSON解析
//  FInterPreterVC.m
//  FInterpreter
//
//  Created by lanouhn on 14-9-11.
//  Copyright (c) 2014年 [email protected] 陳聰雷. All rights reserved.
//

#import "FInterPreterVC.h"
#import "Person.h"
#import "GDataXMLNode.h"
#import "JSONKit.h"
@interface FInterPreterVC ()
@property (nonatomic, retain) NSMutableArray *arr;//用來存儲person對象
@property (nonatomic, retain) Person *per;//用來存儲信息
@property (nonatomic, retain) NSString *str;//存儲讀到的字符串
@end

@implementation FInterPreterVC

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}
/**
 *  解析:按照一種約定好的格式(假象), 有後台開發人員, 按照格式存數據, 由前端按照格式取數據(謹記: 這種格式是由後台開發人員決定的, 我們無權決定)
    解析的本質: 按照約定好的格式取出我們想要數據的過程
    當今比較流行的格式:XML和JSON格式
    XML解析兩種解析原理:
    SAX解析:基於事件回調的解析機制, 就是使用協議以及代理. SAX解析是逐行解析, 讀入數據時只讀入一行, 一行一行的解析, 所以SAX解析占用內存較小, 適合於大數據解析
    DOM解析:一次性將內容全部讀入內存, 將內容讀成樹形結構, 逐層解析, 適合小數據解析
 */
- (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 *btn = [UIButton buttonWithType:UIButtonTypeSystem];
        btn.frame = CGRectMake(60, height, 200, 30);
        btn.backgroundColor = [UIColor greenColor];
        [btn setTitle:titles[i] forState:UIControlStateNormal];
        SEL selector = NSSelectorFromString(methods[i]);
        [btn addTarget:self action:selector forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:btn];
        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];
}
//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 - NSXMLParserDetegate
//當讀取到開始標簽時觸發
- (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.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"]) {
        //為perosn對象開辟空間
        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(@"game over");
    NSLog(@"%@", self.arr);
}

//DOM解析第一種方式
/**
 *  DOM解析使用Google提供的一個開源高效的解析工具GDataXMLNode, 它的效果要比NSXMLParser要快10倍
    使用方式:
    1 先導入系統動態鏈接庫 libxml2.2.dylib
    2 在buildSettings中的Header Search Path中添加/usr/include/libxml2
    3 在buildSettings中的Other Linker Flags中添加-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 *rootElement = [document rootElement];
    //5 獲取根節點的所有子節點
    NSArray *personElements = [rootElement elementsForName:@"person"];
    //6 先獲取數組得到每一個person節點, 然後再得到perosn節點下的子節點
    for (GDataXMLElement *element in personElements) {
        //獲取perosn節點下的name節點
        GDataXMLElement *nameElement = [[element elementsForName:@"name"] firstObject];
        //獲取perosn節點下的gender節點
        GDataXMLElement *genderElement = [[element elementsForName:@"gender"] firstObject];
        //獲取perosn節點下的age節點
        GDataXMLElement *ageElement = [[element elementsForName:@"age"] firstObject];
        //獲取perosn節點下的imageName節點
        GDataXMLElement *imageNameElement = [[element elementsForName:@"imageName"] firstObject];
        //獲取perosn節點下的phoneNumber節點
        GDataXMLElement *phoneNumberElement = [[element elementsForName:@"phoneNumber"] firstObject];
        //1 獲取開始標簽與結束標簽的值
        /*
        NSString *name = [nameElement stringValue];
        NSString *gender = [genderElement stringValue];
        NSString *age = [ageElement stringValue];
        NSString *imageName = [imageNameElement stringValue];
        NSString *phoneNumber = [phoneNumberElement stringValue];
        NSLog(@"=======%@ %@ %@ %@ %@", name, gender, age, imageName, phoneNumber);
         */
        //2 獲取表現中屬性中存儲的數據
        //屬性對應的類是GDataXMLNode
        GDataXMLNode *nameNode = [nameElement attributeForName:@"name"];
        GDataXMLNode *genderNode = [genderElement attributeForName:@"gender"];
        GDataXMLNode *ageNode = [ageElement attributeForName:@"age"];
        GDataXMLNode *imageNameNode = [imageNameElement attributeForName:@"imageName"];
        GDataXMLNode *phoneNumberNode = [phoneNumberElement attributeForName:@"phoneNumber"];
        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
{
    //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];
    //獲取所有的imageName節點
    NSArray *imageNameElements = [document nodesForXPath:@"//imageName" error:nil];
    //獲取所有的phoneNumber節點
    NSArray *phoneNumberElements = [document nodesForXPath:@"//phoneNumber" error:nil];
    //通過循環取出每個節點
    for (int i = 0; i < 3; i++) {
        GDataXMLElement *nameElement = nameElements[i];
        GDataXMLElement *genderElement = genderElements[i];
        GDataXMLElement *ageElement = ageElements[i];
        GDataXMLElement *imageNameElement = imageNameElements[i];
        GDataXMLElement *phoneNumberElement = phoneNumberElements[i];
        NSString *name = [nameElement stringValue];
        NSString *gender = [genderElement stringValue];
        NSString *age = [ageElement stringValue];
        NSString *imageName = [imageNameElement stringValue];
        NSString *phoneNumber = [phoneNumberElement stringValue];
        NSLog(@"-------%@ %@ %@ %@ %@", name, gender, age, imageName, phoneNumber);
    }
}

//系統的解析方式
- (void)handleSystemJSON:(UIButton *)btn
{
    //1 獲取文件路徑
    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Student" ofType:@"json"];
    //2 初始化NSData對象
    NSData *data = [NSData dataWithContentsOfFile:filePath];
    //3 解析
    NSMutableArray *arr = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
    NSLog(@"%@", arr);
}

//JSONKit類的解析方式
/**
 *  對於JSONKit 提供的解析方式,是為NSString,NSData添加分類的方式,在分類中添加了解析的方法.效率僅次於系統的.
 將json格式數據解析成NSArray,NSDictionary.
 而為NSArray,NSDictionary添加的分類的方法,則是將OC的對象,轉化為JSON格式字符串.
 *
 */
- (void)handleStrBtn:(UIButton *)btn
{
    //1 獲取文件路徑
    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Student" ofType:@"json"];
    //2 初始化NSString對象
    NSString *jsonStr = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
    //3 解析
    NSArray *arr = [jsonStr objectFromJSONString];
    NSLog(@"%@", arr);
}

- (void)handleArrBtn:(UIButton *)btn
{
    //1 將OC的數組轉換為json格式化字符串
    NSArray *arr = @[@1,@"bb",@"cc",@"dd",@"ee"];
    //轉化
    NSString *jsonStr = [arr JSONString];
    NSLog(@"%@", jsonStr);
    //2 解析
    NSString *str = [jsonStr objectFromJSONString];
    NSLog(@"%@", str);
}

- (void)handleDicBtn:(UIButton *)btn
{
    //1 將OC的字典轉換為json格式化字符串
    NSDictionary *dic = @{@"name":@1,@"gender":@"man",@"age":@"18"};
    //轉化
    NSString *jsonStr = [dic JSONString];
    NSLog(@"%@", jsonStr);
    //2 解析
    NSString *str = [jsonStr objectFromJSONString];
    NSLog(@"%@", str);
}

- (void)handleDataBtn:(UIButton *)btn
{
    //1 獲取文件路徑
    NSString *fileParth = [[NSBundle mainBundle] pathForResource:@"Student" ofType:@"json"];
    //2 初始化NSData對象
    NSData *jsonData = [NSData dataWithContentsOfFile:fileParth];
    //3 解析
    NSArray *arr = [jsonData objectFromJSONData];
    NSLog(@"%@", arr);
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

- (void)dealloc
{
    self.arr = nil;
    self.per = nil;
    self.str = nil;
    [super dealloc];
}

@end

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved