數據解析 1 數據傳輸過程 前端:請求(iOS/安卓(JAVA)PC(瀏覽器(HTML/CSS/JS))) :OC/JAVA/HTML/CSS/JS 後端:響應(伺服器開發:php/java/.net) 前端和後端交互的"數據格式": XML/JSON 數據解析. XML/"JSON" > OC 客 ...
數據解析
1 數據傳輸過程
前端:請求(iOS/安卓(JAVA)PC(瀏覽器(HTML/CSS/JS))) :OC/JAVA/HTML/CSS/JS
後端:響應(伺服器開發:php/java/.net)
前端和後端交互的"數據格式": XML/JSON
數據解析. XML/"JSON" ----> OC
客戶端發送請求給伺服器,伺服器接收到客戶端的請求之後,返回給客戶端JSON數據.
客戶端需要把伺服器返回的JSON數據轉換為OC的數據格式(數組/字典等).
2 數據解析 :JSON
JSON是一種輕量級的數據格式,一般用於數據交互,伺服器返回給客戶端的數據,一般都是JSON格式或者XML格式(文件下載除外),JSON是javascript語言的一個子集.javascript是個腳本語言(不需要編譯),用來給HTML增加動態功能.
註: javascript和java沒有半毛錢的關係!
JSON的格式很像OC中的字典和數組
NSJSONSerialization的常見方法
JSON數據 à OC對象
JSON – OC 轉換對照表
JSON |
OC |
大括弧 { } |
NSDictionary |
中括弧 [ ] |
NSArray |
雙引號 ” “ |
NSString |
數字 10、10.8 |
NSNumber |
3 解析數據的工具分類
- JSON 解析的種類: SBJson, JSONKit, NSJSONSerialization
- XML 解析的種類: DOM, SAX
4 JSON數據解析方法:
在iOS中,常見的JSON數據解析方案有4種:
第三方框架: SBJson ,JSONKit, TouchJson.性能從左到右,依次變差.
蘋果原生(自帶):NSJSONSerialization (性能是最好的.iOS5以後推出).
5 解析JSON數據
<1>反序列化(解析):
將從伺服器接收到的JSON數據(二進位數據)轉換成OC數據類型(NSArray,NSDictionary等.)的過程.
目的: JSON數據 --> OC對象; 得到數據字典或者數據數組
好處: 簡化程式的開發,方便後續的字典轉模型.
方法:
+(id)JSONObjectWithData:(NSData *)data options:(NSJSONReadingOptions)
opt error:(NSError **)error;
<2>序列化:
將數組或者字典發送給伺服器之前,轉換成二進位數據.
目的:OC對象 --> JSON數據;得到二進位JSON數據 NSData;
好處:方便網路傳輸,提高傳輸速度.
方法:
+(NSData *)dataWithJSONObject:(id)obj options:(NSJSONWritingOptions)opt error:(NSError **)error;
"需要註意的是,在做序列化之前,一定要檢測一下對象是否能夠被序列化."
// 在做序列化之前,一定使用 isValidJSONObject 檢測一下要序列化的對象,是否能夠正確被序列化
// 避免出現閃退!
6.JSON標準化(會簡單的修改JSON數據)
具體思路:
> 發送網路請求
> 用字元串接收JSON數據
> 將JSON格式標準化
> 將標準化之後的JSON字元串轉換成二進位數據
> 將標準的JSON二進位數據轉化為OC數據
7. 學會將不標準的 JSON 數據解析出來!
> 先把jSON數據轉為字元串
> 利用字元串的方法,修改JSON數據
> 將標準化之後的json字元串轉換成二進位數據
> 將標準的JSON二進位數據轉換成 OC 數據
8 XML 全稱是Extensible Markup Language,譯作“可擴展標記語言
XML特征:
1、XML是一種標記語言,很類似HTML
2、XML的設計宗旨是傳輸數據,而非顯示數據
3、XML標簽沒有被預定義。您需要自行定義標簽。
4、XML被設計為具有自我描述性。
5、XML是W3C的推薦標準
XML是獨立於軟體和硬體的信息傳輸工具。 目前,XML在Web中起到的作用不會亞於一直作為 Web 基石的 HTML。 XML無所不在。XML是各種應用程式之間進行數據傳輸的最常用的工具,並且在信息存儲和描述領域變得越來越流行。
XML常用的三種解析方式SAX/DOM/PULL。
SAX是一個用於處理XML事件驅動的“推”模型,優點是一種解析速度快並且占用記憶體少的xml解析器,它需要哪些數據再載入和解析哪些內容。缺點是它不會記錄標簽的關係,而要讓你的應用程式自己處理,這樣就增加了你程式的負擔。
DOM是一種文檔對象模型,DOM可以以一種獨立於平臺和語言的方式訪問和修改一個文檔的內容和結構。Dom技術使得用戶頁面可以動態地變化,如可以動態地顯示或隱藏一個元素,改變它們的屬性,增加一個元素等,Dom技術使得頁面的交互性大大地增強。缺點是DOM解析XML文件時,會將XML文件的所有內容以文檔樹方式存放在記憶體中。
Pull解析和Sax解析很相似,Pull解析和Sax解析不一樣的地方是pull讀取xml文件後觸發相應的事件調用方法返回的是數字還有pull可以在程式中控制想解析到哪裡就可以停止解析。
SAX解析 :
NSXMLParserDelegate
// 1. 實例化 XML 的 SAX 解析器!
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
// 2. 設置解析器代理.
delegate = self;
// 3. 開始解析 XML 文檔
// 一旦調用了下麵的開始解析方法,就會自動調用代理方法,解析 XML 文檔!
[parser parse];
#pragma NSXMLParserDelegate
- (void)parserDidStartDocument:(NSXMLParser *)parser{
NSLog(@"1.XML文檔解析開始!");
}
// 開始解析元素的時候就會調用!XML文檔中有多少個元素就會調用多個次!
// elementName:元素名稱!
// attributeDict:屬性字典!當前元素對應的屬性字典!
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(nullable NSString *)namespaceURI qualifiedName:(nullable NSString *)qName attributes:(NSDictionary<NSString *, NSString *> *)attributeDict
{
NSLog(@"2.開始解析:%@元素,元素屬是:%@",elementName,attributeDict);
// 判斷:只有元素 vedio 的屬性字典是需要的內容!
if ([elementName isEqualToString:@"vedio"]) {
// 字典轉模型
CZVideo *video = [CZVideo videoWithDict:attributeDict];
// 添加到數據源中
[self.videos addObject:video];
}
}
// 發現元素內容的時候就會調用!
// string :元素內容!
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
NSLog(@"3.發現元素內容:%@",string);
}
// 元素解析結束的時候就會調用,XML文檔中有多少個元素就會調用多個次!
// elementName :元素名稱
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(nullable NSString *)namespaceURI qualifiedName:(nullable NSString *)qName
{
NSLog(@"4.元素%@解析結束",elementName);
}
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
NSLog(@"5.XML文檔解析結束!");
}
DOM 解析
DOM解析的特點: 一次性載入文檔之後再解析.(需要導入靜態庫libxml2.tbd)
(1.獲得 DOM 對象 2.獲得根元素內容 3.遍歷根元素的"屬性數組"或者"子元素數組" 4.層層遍歷元素或者屬性內容... 5.根據節點的 name 屬性 和 stringValue 屬性獲得對應的值. 6. 給數據模型賦值)
// 1.獲得 DOM 對象!
GDataXMLDocument *dom = [[GDataXMLDocument alloc] initWithData:data options:0 error:NULL];
// 2.利用 dom 對象操縱 XML 節點!
// 利用 DOM 對象獲得需要的文檔內容!---> 根元素內容!
GDataXMLElement *rootElement = dom.rootElement;
// 3遍歷根元素的子元素,取出對應的子元素
[rootElement.children enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop)
//4.遍歷 元素的屬性數組,取出每一個屬性的值.
[vedioElement.attributes enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop)