iOS ---解析

解析:從事先約定好的格式中提取數(shù)據(jù)挚币。這種格式是前端開發(fā)人員和后臺約定好的输硝,約定獲取的數(shù)據(jù)是什么格式的开瞭,就是用什么格式的解析方式(一般都是前端開發(fā)人員聽從后臺的)
解析的前提:按照約定好的格式录煤,數(shù)據(jù)提供方按照格式提供數(shù)據(jù)捞稿、數(shù)據(jù)獲取方按照格式獲取數(shù)據(jù)
解析常見的為XML解析又谋、 JSON解析

JSON解析

{
    "reason":"success",
    "result":[
        {
            "movieId":"216609",
            "movieName":"詭八樓",
            "pic_url":"http:\/\/v.juhe.cn\/movie\/picurl?2583083"
        },
        {
            "movieId":"216391",
            "movieName":"摩登森林之美食總動員",
            "pic_url":"http:\/\/v.juhe.cn\/movie\/picurl?2583246"
        },
        {
            "movieId":"216162",
            "movieName":"龜兔再跑",
            "pic_url":"http:\/\/v.juhe.cn\/movie\/picurl?2583181"
        }
         ......
       ],

"error_code":0
}

上面為JSON格式數(shù)據(jù)拼缝,是一個大字典,字典的鍵值對中的值又包括數(shù)組彰亥。數(shù)組中又包含好多個字典咧七,每個字典的鍵值對就是我們需要取出的數(shù)據(jù)
json文件有兩種結(jié)構(gòu):

對象:"名稱/值"對的集合。不同的語言中任斋,它被理解為對象继阻,記錄,結(jié)構(gòu)废酷,字典瘟檩,哈希表,有鍵列表澈蟆,或者關(guān)聯(lián)數(shù)組墨辛。以"{" 開始, 以"}" 結(jié)束, 是"名稱/值"對的集合趴俘。名稱和值中間用":"隔開睹簇。多個"名稱/值"對之間用 ", " 隔開

數(shù)組: 值得有序列表。在大部分語言中寥闪,它被理解為數(shù)組太惠。以"[" 開始, 以"]" 結(jié)束橙垢,中間是數(shù)據(jù)垛叨。數(shù)據(jù)以 ", " 分隔

JSON中的數(shù)據(jù)類型:字符串,數(shù)值柜某,BOOL嗽元,對象,數(shù)組

JSON解析工具:JSONKit喂击、 NSJSONSerialization撒强、 TouchJSON 和SBJSON等夯辖,其中NSJSONSerialization是系統(tǒng)提供的解析類锹漱,其解析效率是最高的
其中關(guān)于其他第三方的JSON解析工具 在http://www.reibang.com/p/a54d367adb2a 里面會有講解腋逆,這里只是分享了系統(tǒng)自帶的JSON解析工具NSJSONSerialization

NSJSONSerialization 解析步驟:

1.得到j(luò)son文件,并且轉(zhuǎn)換為data類型
step1.1文件路徑

NSString *jsonPath = [[NSBundle mainBundle] pathForResource:@"MovieList" ofType:@"text"];

step1.2轉(zhuǎn)化為 nsdata類型

NSData *jsonData = [NSData dataWithContentsOfFile:jsonPath];//根據(jù)路徑獲取data類型數(shù)據(jù)

step1.3解析json 數(shù)據(jù) jsonkit sbjson touchjson 三種解析第三方 但是還是系統(tǒng)提供的json解析更好用

NSError *error = nil;
    NSDictionary *resultDic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragmentserror:&error];  //系統(tǒng)提供的json解析數(shù)據(jù)的工具
    //error錯誤  里面包含了解析是處的錯誤监嗜,一般打印是為了驗證錯誤點
    NSLog(@"%@", error);

2.判斷解析獲得的數(shù)據(jù)是否正常(是否是我們想要的數(shù)據(jù)) //這一步是在驗證谐檀,真正開發(fā)時,可以不使用

if (resultDic) {  //如果解析的數(shù)據(jù)不為空
        //判斷當前的對象是否支持json格式
        if ([NSJSONSerialization isValidJSONObject:resultDic]) {
            NSData *strData = [NSJSONSerialization dataWithJSONObject:resultDic options:NSJSONWritingPrettyPrinted error:nil];
            //將data 轉(zhuǎn)換為字符串
            if (strData != nil) {
                NSString *str = [[NSString alloc] initWithData:strData encoding:NSUTF8StringEncoding];
                NSLog(@"%@", str);
            }
        }
    }

XML解析

<?xml version="1.0" encoding="utf-8"?> <!--此行包含XML的版本信息和編碼格式-->
<students><!--這是開始標簽裁奇,也就是根節(jié)點-->
    <student attribute = "七班班寶" position = "bu"><!--student為根節(jié)點的子節(jié)點桐猬,name節(jié)點的父節(jié)點, attribute是它的屬性-->
        <name>趙威</name><!--李帥為name節(jié)點的值-->
        <sex>無</sex>
        <age>14</age>
    </student>
    <student attribute = "七班班長">
        <name>鵬鵬</name>
        <sex>隨條件改變</sex>
        <age>17</age>
    </student>
    <student attribute = "banzhangtamei">
        <name>lisi</name>
        <sex>隨他呢</sex>
        <age>33</age>
    </student>
</students><!--節(jié)點的結(jié)束標簽都是以/加標簽名稱組成 -->

上面為XML格式數(shù)據(jù)刽肠。
XML: Extensible Markup language (可拓展標記語言)溃肪,主流數(shù)據(jù)格式之一免胃,可以用來存儲和傳輸數(shù)據(jù)
節(jié)點:使用一對標簽表示:起始和結(jié)束標簽 <節(jié)點名> 數(shù)據(jù)或其他節(jié)點</節(jié)點名>
XML數(shù)據(jù)結(jié)構(gòu):有且只有一個根節(jié)點,如上面代碼中的students惫撰, 但是在根節(jié)點中可以嵌套好多子節(jié)點羔沙,子節(jié)點可以作為父節(jié)點嵌套下一級子節(jié)點 如<student> <name> </name> </student> student 作為父節(jié)點students的子節(jié)點,又是name節(jié)點的父節(jié)點
節(jié)點中可以有值厨钻,存儲在一對標簽中 如 <name>趙威</name> 節(jié)點的值就是 趙威
這樣按照層級的層次把數(shù)據(jù)存儲在節(jié)點中扼雏,獲取數(shù)據(jù)也是調(diào)取節(jié)點中的數(shù)據(jù)

XML解析的作用:數(shù)據(jù)交換 內(nèi)容管理 用作配置文件

XML解析又分為SAX解析和DOM解析

XML解析之SAX解析

SAX: Simple API for XML±蚱玻基于事件驅(qū)動的解析方式呢蛤,逐行進行解析數(shù)據(jù)(采用協(xié)議回調(diào)機制)。

SAX解析使用的類:NSXMLParser 棍郎。NSXMLPraser是系統(tǒng)自帶的XML解析類,采用SAX方式解析數(shù)據(jù)银室。
解析過程由NSXMLPraserDelegate協(xié)議方法回調(diào)
解析過程:開始標簽->取值->結(jié)束標簽->取值

@interface RootViewController ()<NSXMLParserDelegate>//簽協(xié)議
@property (nonatomic, strong) NSMutableDictionary *dic;//用來student節(jié)點中的值
@property (nonatomic ,strong) NSMutableArray *allDataArray;//用來盛放所有的student節(jié)點轉(zhuǎn)換的字典
@property (nonatomic, strong) NSMutableString *valueString;//用來拼接節(jié)點中間的值
@end
//得到需要解析的數(shù)據(jù)   獲取數(shù)據(jù)文件所在的地址
    NSString *saxPath = [[NSBundle mainBundle] pathForResource:@"XMLDemo" ofType:@"xml"];
    //獲取data
    NSData *saxData = [NSData dataWithContentsOfFile:saxPath];
    //創(chuàng)建sax解析的工具類對象
    NSXMLParser *saxParser = [[NSXMLParser alloc] initWithData:saxData];
    //指定代理
    saxParser.delegate = self;
    //開始解析 sax解析是一個同步的過程
   BOOL isParser = [saxParser parse];
    //判斷解析成功
    if(isParser)
        NSLog(@"解析完成");
    else
        NSLog(@"解析失敗");
#pragma mark --sax解析代理方法
//開始解析
- (void)parserDidStartDocument:(NSXMLParser *)parser {
     NSLog(@"開始解析");
    //初始化數(shù)組(遍歷構(gòu)造器)   在開始解析里面初始化保存數(shù)據(jù)的數(shù)組
    self.allDataArray = [NSMutableArray array];
}

//開始解析某個節(jié)點
/*
elementName:標簽名稱
namespaceURI:命名空間指向的鏈接
qualifiedName:命名空間的名稱
attributtes:節(jié)點的所有屬性(可以多個)
 */
- (void)parser:(NSXMLParser *)parser didStartElement:(nonnull NSString *)elementName namespaceURI:(nullable NSString *)namespaceURI qualifiedName:(nullable NSString *)qName attributes:(nonnull NSDictionary<NSString *,NSString *> *)attributeDict {
    NSLog(@"開始解析%@節(jié)點", elementName);
    //當開始解析student子節(jié)點的時候涂佃,就應(yīng)該初始化字典,因為一個字典就對應(yīng)著一個學生的信息
    //每解析一個student蜈敢,就初始化一次
    if ([elementName isEqualToString:@"student"]) {
        self.dic = [NSMutableDictionary dictionary];
    }
}

//獲取節(jié)點之間的值
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    NSLog(@"取值---%@", string);
//    if(self.valueString){//說明有值
//        [self.valueString appendString:string];
//    }else{
//        self.valueString = [NSMutableString stringWithString:string];
//    }
    //這里會把空格覆蓋掉
    if (string != nil) {
        self.valueString = [NSMutableString stringWithString:string];
    }
    
}

//某個節(jié)點結(jié)束取值
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    NSLog(@"結(jié)束%@節(jié)點的解析", elementName);
    
    if ([elementName isEqualToString:@"name"]) {//說明name節(jié)點已經(jīng)取值結(jié)束
        [self.dic setObject:self.valueString forKey:elementName];
    }
    if ([elementName isEqualToString:@"age"]) {
        [self.dic setObject:self.valueString forKey:elementName];
    }
    if ([elementName isEqualToString:@"sex"]) {
        [self.dic setObject:self.valueString forKey:elementName];
    }
    
//    [self.dic setObject:self.valueString forKey:elementName];
    
    if ([elementName isEqualToString:@"student"]) {//一個student已經(jīng)解析完畢
        [self.allDataArray addObject:self.dic]; //把studnet的字典添加到數(shù)組中
    }
    self.valueString = nil; 
}

//結(jié)束解析 在結(jié)束解析協(xié)議方法中內(nèi)獲取全部的數(shù)據(jù)
- (void)parserDidEndDocument:(NSXMLParser *)parser {
    //就可以使用解析完成的數(shù)據(jù)
    NSLog(@"%@", self.allDataArray);
    NSLog(@"整個解析結(jié)束");
}

//報告不可恢復的解析錯誤
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
    NSLog(@"解析出現(xiàn)錯誤:%@", parseError);
}

XML解析之DOM解析

DOM: Document Object Model(文檔對象類型)辜荠。DOM方式解析XML時,讀入整個XML文檔并構(gòu)建一個駐留內(nèi)存的樹結(jié)構(gòu)(節(jié)點數(shù)),通過遍歷節(jié)點樹結(jié)構(gòu)可以檢索任意XML節(jié)點抓狭,讀取他的屬性和值伯病。而且通常情況下,可以借助XPath,直接查詢XML節(jié)點否过。
DOM是基于文檔的解析方式午笛。

DOM解析需要導入的庫 libxml2.dylib(ios7之后改為libxml2.tdb) GDataXMLNode
GDataXMLNode是Google提供的開元XML解析類,對libxml2.tdb進行了Object-C的封裝苗桂,能對較小或中等的xml文檔進行讀寫操作并且支持XPath語法
使用GDataXMLNode使用方法
1.獲取GDataXMLNode.h/m文件药磺,將GDataXMLNode.h/m文件添加到工程中
2.向工程中增加"libxml2.dylib(ios7之后改為libxml2.tdb) "動態(tài)庫
3.在工程的"Build Settings"頁中找到"Header Search Path"項,添加/usr/include/libxml2
4.導入"GDataXMLNode.h"文件到頭文件中煤伟,如工程能編譯通過癌佩,則說明GDataXMLNode添加成功

解析過程

//用來盛放所有的字典
    NSMutableArray *datasourse = [NSMutableArray array];
    
    //得到需要解析的數(shù)據(jù)(xml文件)
    NSString *xmlPath = [[NSBundle mainBundle] pathForResource:@"XMLDemo" ofType:@"xml"];
    //轉(zhuǎn)換為NSData類型
    NSData *xmlData = [NSData dataWithContentsOfFile:xmlPath];
    
    //構(gòu)建document文檔對象
    NSError *error = nil;
    GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:xmlData options:0 error:&error];//options:的值為0,這個是預留的
    
    //找到根節(jié)點,就是students
    GDataXMLElement *rootElement = [doc rootElement];
    
    //找到根節(jié)點的所有子節(jié)點,就是所有的student
    NSArray *allSubNotes = [rootElement elementsForName:@"student"];
    //找到student節(jié)點的所有子節(jié)點
    for (GDataXMLElement *item in allSubNotes) {
        //每次循環(huán)開始的時候便锨,說明是一個新的student節(jié)點围辙,我們需要字典來盛放他所有的值
        //防止引用計數(shù)加一,使用初始化方法
        
        NSLog(@"%@", item.attributes[0]);
        NSMutableDictionary *studentDic = [NSMutableDictionary dictionary];
        
        //得到name節(jié)點
        NSArray *nameArray = [item elementsForName:@"name"];
//        GDataXMLElement *nameElement = [nameArray objectAtIndex:0];
        GDataXMLElement *nameElement = [nameArray firstObject];
        //取值
        NSString *name = [nameElement stringValue];
        [studentDic setObject:name forKey:@"name"];
        //取出sex
        NSArray *sexArray = [item elementsForName:@"sex"];
        GDataXMLElement *sexElement = [sexArray firstObject];
        NSString *sex = [sexElement stringValue];
        [studentDic setObject:sex forKey:@"sex"];
        
        //取出age
        NSArray *ageArray = [item elementsForName:@"age"];
        GDataXMLElement *ageElement = [ageArray firstObject];
        //取值
        NSString *age = [ageElement stringValue];
        [studentDic setObject:age forKey:@"age"];
        
        //將字典添加到可變數(shù)組中
        [datasourse addObject:studentDic];
    }

SAX解析和DOM解析的區(qū)別:

SAX只能讀不能寫放案,DOM解析不知能讀姚建,還能寫(增加節(jié)點)
如果文檔小一些,DOM解析效率更高一些
DOM解析基于文檔卿叽,SAX解析基于事件
如果數(shù)據(jù)量相同時桥胞,DOM解析效率更高
SAX解析是逐行解析恳守,DOM解析是整個文檔來操作的
數(shù)據(jù)量比較大時,適用于SAX解析

JSON解析和DOM解析的優(yōu)缺點

XML優(yōu)缺點

優(yōu)點:

1.格式統(tǒng)一贩虾,符合標準
2.容易與其他系統(tǒng)進行遠程交互催烘,數(shù)據(jù)共享比較方便

缺點:

1.XML格式文件龐大,格式復雜缎罢,傳輸暫用寬帶
2.服務(wù)器端和客戶端都需要花費大量代碼來維護XML伊群,不論服務(wù)器端還是客戶端都使代碼變得異常復雜和不容易維護
3.刻畫段不同瀏覽器之間解析XML的方式不一致,需要重復編寫很多代碼
4.服務(wù)器端和客戶端解析MXL花費資源和時間

JSON優(yōu)缺點
優(yōu)點:

1.數(shù)據(jù)格式比較簡單策精,易于讀寫舰始,格式都是壓縮的,占用帶寬小咽袜。
2.易于解析這種語言丸卷。
3.支持多種語言,包括ActionScrip, C, C#, ColdFusion, Java, JavaScript, Perl, PHP, Python, Ruby等語言服務(wù)器端語言询刹,便于服務(wù)器端的解析
4.因為JSON格式能夠直接為服務(wù)器端代碼使用谜嫉,大大簡化了服務(wù)器端和客戶端的代碼開發(fā)量,大師完成的任務(wù)不變凹联,且易于維護沐兰。

缺點:

1.沒有XML格式這么推廣的深入人心和使用廣泛,沒有XML那么通用性蔽挠。
2.JSON格式目前在Web Service中推廣還屬于初級階段

比較 :

xml在布局文件比json強太多住闯,但是json更便于傳輸
xml是可拓展的語言,隨便往里面添加標簽澳淑,標簽名字可以隨便改變

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末比原,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子偶惠,更是在濱河造成了極大的恐慌春寿,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件忽孽,死亡現(xiàn)場離奇詭異绑改,居然都是意外死亡,警方通過查閱死者的電腦和手機兄一,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進店門厘线,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人出革,你說我怎么就攤上這事造壮。” “怎么了?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵耳璧,是天一觀的道長成箫。 經(jīng)常有香客問我,道長旨枯,這世上最難降的妖魔是什么蹬昌? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮攀隔,結(jié)果婚禮上皂贩,老公的妹妹穿的比我還像新娘。我一直安慰自己昆汹,他們只是感情好明刷,可當我...
    茶點故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著满粗,像睡著了一般辈末。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上映皆,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天本冲,我揣著相機與錄音,去河邊找鬼劫扒。 笑死,一個胖子當著我的面吹牛狸膏,可吹牛的內(nèi)容都是我干的沟饥。 我是一名探鬼主播,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼湾戳,長吁一口氣:“原來是場噩夢啊……” “哼贤旷!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起砾脑,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤幼驶,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后韧衣,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體盅藻,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年畅铭,在試婚紗的時候發(fā)現(xiàn)自己被綠了氏淑。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡硕噩,死狀恐怖假残,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情炉擅,我是刑警寧澤辉懒,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布阳惹,位于F島的核電站,受9級特大地震影響眶俩,放射性物質(zhì)發(fā)生泄漏莹汤。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一仿便、第九天 我趴在偏房一處隱蔽的房頂上張望体啰。 院中可真熱鬧,春花似錦嗽仪、人聲如沸荒勇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽沽翔。三九已至,卻和暖如春窿凤,著一層夾襖步出監(jiān)牢的瞬間仅偎,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工雳殊, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留橘沥,地道東北人。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓夯秃,卻偏偏與公主長得像座咆,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子仓洼,可洞房花燭夜當晚...
    茶點故事閱讀 44,611評論 2 353

推薦閱讀更多精彩內(nèi)容