iOS基礎-數據解析方法初步總結-(XML,JSON歡迎指正)

小時候的記憶與大家一起分享,愿君安好!
  • 解析的基本概念

  • 解析: 從事先規定好的格式中提取數據
  • 解析的前提: 提前約定好格式,數據提供方按照格式提供數據,數據獲取方則按照格式獲取數據 OS開發常見的解析: XML解析,JSON解析


XML_stu.txt在我們的工程中引入要解析的文件這個只是一個簡單例子(根據數據創建并引入一個Student類去處理數據)

XML解析 :

  • 可拓展標記語言 (eXtensible Markup Language)

XML數據格式的功能:

1 : 數據交換
2 : 內容管理
3 : 用作配置文件

XML數據結構的語法

1 : 文檔聲明 --在 XML文檔在最前面必須寫一個文檔聲明.

  • 1.1 簡單的文檔聲明 : <?xml version="1.0"?>
  • 1.2 用 encoding 屬性, 來說明文檔字符編碼 :<?xml version="1.0" encoding="UTF-8">

2 : (元素 Element)節點使用一對標簽表示:起始和結束標簽

  • (1)有元素內容:<name>你</name>
  • (2)無元素內容:<name></name> 而且一個元素可以嵌套若干個子元素,但不能出現交叉嵌套

3 : 根節點是起始節點,只有一個,節點可以嵌套
4 : 節點可以有值,存儲在一對標簽中.
5 : 規范的 XML 文檔最多只有一個根元素, 其他的都是根元素的子孫元素;
6 : 在XML中, 空格和換行,都會被當做具體的內容去處理;
7 : 屬性 (Atribute) : 一個元素可以擁有多個屬性,例如 <video name="小黃人" hobby="banana"/> [video元素擁有name, hobby兩個屬性]

  • (1): 屬性的值必須使用""或者''括住
  • (2): 屬性表示的信息也可以用子元素來表示,例如:
    <video>
    <name>小黃人</name>
    <hobby>banana</hobby>
    </video>

解析方式,逐行進行解析

1:打開XML文檔
2: 開始節點 (開始標簽)
3: 發現元素里面的內容
4: 結束節點 (結束標簽)
5: 循環開始, 直到遇到</persons>解析才徹底結束

iOS中XML解析方式有很多

1: 蘋果原生:NSXMLParser --SAX方式解析,使用簡單
2: 第三方框架:
(1)libxml2 : 純C語言,默認被包含進了iOS SDK, 同時支持DOM 和 SAX 解析
(2)GDataXMl: DOM的解析方式, 是由谷歌開發的, 底層基于libxml2

  • 第一種 : SAX解析 (系統自帶的XML方法)

SAX 工具 : Simple API for XML. 基于事件驅動的解析方式,逐行解析數據.(采用協議回調機制)

1 : NSXMLParser: NSXMLParser是iOS自帶的XML解析類,采用SAX方式解析數據
2 : 解析過程由NSXMLParserDelegate協議方法回調
3 : 解析過程: 開始標簽-> 取值(model賦值) -> 結束標簽 ->取值(這個時候我們要了解是否要還給我們model賦值)

  • 要使用iOS中系統的SAX解析 需要遵守 NSXMLParserDelegate 協議
    @interface ViewController ()<NSXMLParserDelegate>
  • 聲明屬性 數據源數組 用于存儲解析數據給你使用
    @property (nonatomic, strong) NSMutableArray *data;
  • 聲明一個用于存儲當前的標簽名字的屬性 (后面具體使用)
    @property (nonatomic, copy) NSString *currentElement;
  • 在一個觸發的行為里面開始實現數據解析我這里在一個控制器里面使用點擊方法

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
// [NSBundle mainBundle] 代表的是你的應用包(其實就是你Xcode左面的那個文件夾欄)
// [pathForResource:@"文件名" ofType:@"文件格式"];
NSString *path = [[NSBundle mainBundle] pathForResource:@"XML_stu" ofType:@"txt"];
// 通過文件路徑 創建一個NSData對象
NSData *data = [NSData dataWithContentsOfFile:path];
// SAX解析使用類

 parser.delegate = self;```
// 開始解析  執行這個方法
```   [parser parse];```
}

- ###執行代理方法
- ####第一步 : 開始解析文檔
// 1 : 開始解析文檔  
```- (void)parserDidStartDocument:(NSXMLParser *)parser
{
//我們需要解析文檔了 就需要自己保存解析的數據  在這里初始化數據源數組
 self.data = [NSMutableArray array];
}```

- ####第二步 : 檢測到開始標簽
-  // 第一個參數:類
- // 第二個參數: elementName 標簽的名字
- // 以下三個基本為nil,一般不會使用
- // 第三個參數: 節點里面的命名空間(xmlns)
- // 第四個參數: qName 這個我還沒弄明白 大家誰知道可以幫助一下 等我知道來修改
- // 第五個參數: attributeDict 標簽的屬性
// 2 : 檢測到開始標簽

> 
```code
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict
{// 給currentElement 賦值 這個屬性就是記錄每次的檢測的開始標簽(其實目的就是對應的Student的屬性去給model賦值)
 self.currentElement = elementName;
// 如果標簽的名字是student 則表示 要創建model(這里就是Student類實例對象)  并添加到數據源數組
 if ([elementName isEqualToString:@"student"])
 {
     Student *model = [Student new];
     [self.data addObject:model];
 }
 NSLog(@"<開始標簽名>== %@", elementName);  
}
  • 第三步 : 檢測到標簽的值 * ( 這一步 : 我的理解是 當找到不管是開始標簽還是結束標簽都回去找標簽的對應值 所以在后面的第四步 需要讓 self.currentElement = nil 不然結束標簽對應\n 也是說沒有值 那么導致又一次走給Model賦值結果Model值就沒有給對給成了對應的結束標簽的一般空值 我們要的是開始標簽對應的值所以這樣操作)*

  • // 第一個參數 : 類
  • // 第二個參數 : 對應的標簽下的值
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
//  將檢測到的值 存入Model的具體屬性(*根據獲取的標簽的名字通過KVC賦值*)
//  給數組的最后的 model賦值
  [[self.data lastObject] setValue:string forKey:self.currentElement];
  NSLog(@"<string值=> == %@ ", string);
  NSLog(@"<key=> == %@",self.currentElement);
}```

- ###第四步 : 檢測到結束標簽
// 4 : 檢測到結束標簽

>```obj
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
// 這里上面已經說過結束標簽找到后依然會走第三步去賦值   所以我們讓Key為空就不會把我們已經存在的值去改掉了
    self.currentElement = nil;
    NSLog(@"<結束標簽>== %@", elementName);
}
  • 第五步 : 結束解析文檔

// 5 : 結束解析文檔 (這里你可以做一些操作,比如打印你的數據源數組看看數據解析是否成功 我這里的Student類重寫了description方法可以直接打印看到數據不然看到地址)

  • (void)parserDidEndDocument:(NSXMLParser *)parser
    {
    for (Student *stu in self.data)
    {
    NSLog(@"%@",stu);
    }
    }```


  • 第二種方法 : DOM工具:(谷歌公司封裝的OC代碼塊 第三方工具)

** DOM: Document Object Model (文件對象模型) . DOM方式解析XML時, 讀入整個XML文檔并構建一個駐留內存的樹結構(節點樹), 通過遍歷樹結構可以檢索任意XML節點, 讀取它的屬性和值. 而且通常情況下, 可以借助XPath, 直接查詢XML節點.**

  • GDataXMLNode :

1 : 采用DOM方式解析數據
2 : iOS包含一個C語言的動態鏈接庫libxml2.tbd,解析熟讀比NSXMLParser快.
3 :GDdataXMLNode是Google提供的XML解析類, 對libxml2.tbd(xcode7以前是 .dylib)進行了Objective-C的封裝,能對較小或中等的xml文檔進行讀寫操作且支持Path語法.

  • 使用方法:

1 : 獲取GDataXMLNode.h /.m 文件,將GDataXMLNode.h /.m文件添加到工程中
2 : 向工程中增加”libxml2.tbd”動態庫
3 : 在工程的”Build Settings”頁中找到”Header Search Path”項,添加 "/usr/include/libxml2 "
4 : 導入”GDataXMLNode.h / .m” 文件到頭文件中,如工程能編譯通過,則說明GDataXMLNode添加成功.

屬性和方法:



  • 這個代碼較少我直接把整個.m放上供參考

#import "Vc2ViewController.h"
#import "GDataXMLNode.h"
#import "Student.h"
@interface Vc2ViewController ()
//數據源數組
@property (nonatomic, strong) NSMutableArray *dataArray;
@end

@implementation Vc2ViewController

    [super viewDidLoad];}```

```obj
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    self.dataArray = [NSMutableArray array];
    NSString *path = [[NSBundle mainBundle] pathForResource:@"XML_stu" ofType:@"txt"];
   NSData *data = [NSData dataWithContentsOfFile:path];
   NSError *error = nil;```
    // GDataXMLDocument  XML的DOM解析使用的類
    // 第一個參數 : 解析的data對象
    // 第二個參數 : 一般就是0
    // 第三個參數 : error信息
  ```  GDataXMLDocument *document = [[GDataXMLDocument alloc] initWithData:data options:0 error:&error];```
   ///獲取到根節點里面所有的東西,也就是說獲取到students里面包含的所有東西
  ```obj
  GDataXMLElement *rootElment = [document rootElement];
    NSLog(@"<rootElement == > == %@",rootElment);
    for ( GDataXMLElement *subElement in rootElment.children)
    {
        // 在這獲取到的subElement保存的是student標簽里面的內容,所以這里創建對象
        Student *student = [Student new];
        [self.dataArray addObject:student];
           for (GDataXMLElement *element in subElement.children)
        {
            //  element 保存的就是student標簽的所有子標簽
            // 根據標簽的名字給 屬性賦值
            // element.name 標簽的名字
            // element.stringValue 標簽的值
// 第一種賦值方法: 逐一對應屬性賦值
            if ([element.name isEqualToString:@"name"])
            {
                student.name = element.stringValue;
            }
            if ([element.name isEqualToString:@"gender"])
            {
                student.gender = element.stringValue;
            }
            if ([element.name isEqualToString:@"hobby"])
            {
                student.hobby = element.stringValue;
            }
            if ([element.name isEqualToString:@"age"])
            {
                student.age = [element.stringValue integerValue];
            }

// 第二種: 賦值方法 setValue 的方法賦值更簡單: (2 選 1 即可 )
            [stu setValue:tempE.stringValue forKey:tempE.name];
        }
        NSLog(@"<subElement>==%@",subElement);
        for (Student *stu in self.dataArray)
        {
            NSLog(@"<學生>= %@",stu);
        }
}
}```
___
____

- #XML的優缺點: 
  -  優點 : 
1 : 格式統一,符合標準
2 : 容易與其他系統進行遠程交互,數據共享比較方便

 -   缺點:
1 : XML文件格式文件龐大, 格式復雜, 傳輸占用帶寬.
2 : 服務器端和客戶端都需要花費大量代碼來解析XML,不論服務器端還是客戶端都使用代碼變得異常復雜和不容易維護
3 : 客服端不容瀏覽器之間解析XML的方式不一致,需要重復編寫很多代碼
4 : 服務器端和客戶端解析XML花費資源和時間
____
____
____
#JOSN解析 :  

- ###JSON (JavaScript Object Notation) 是一種輕量級的數據交換格式.JSON采用完全獨立于語言的文本格式,易于閱讀和編寫,同時也易于機器解析和生成.這些特性使JSON成為理想的數據交換語言.


- ###JSON文件有兩種結構: 
> - 對象: “名稱/值” 對的集合 .不同的語言中,它被理解為對象,記錄, 結構, 字典, 哈希表, 有鍵列表, 或者關聯數組. 以 ” {“ 開始,以 “}” 結束, 是”名稱/值” 對的集合.  名稱和值中間用 “:” 隔開, 多個 “名稱/值” 對之間用 “,” 隔開 .
 - 數組: 值的有序列表. 在大部分語言中, 它被理解為數組 . 以 “[“ 開始, 以 ”]” 結束, 中間是數據. 數據已 “,” 分隔.
 -  JSON中的數據類型 : 字符串, 數值 ,BOOL, 對象,數組

![舉例](http://upload-images.jianshu.io/upload_images/1523603-219928ee8be06d44.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

- ##功能: 
>- ###數據交換
 - ###內容管理
 - ###配置文件



![引入這個我們需要解析的數據 JSON_stu.txt](http://upload-images.jianshu.io/upload_images/1523603-2417bb8b68e61249.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
- ##NSJSONSerialization工具:(系統自帶的)
> ````- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{````
   //獲取文件路徑
   ```` NSString *path = [[NSBundle mainBundle]pathForResource:@"JSON_stu" ofType:@"txt"];````
//創建數據對象 
```` NSData *data = [NSData dataWithContentsOfFile:path];  ````
  //   NSJSONReadingMutableContainers  返回一個數組或者字典
//    NSJSONReadingMutableLeaves  返回一個字符串
//    NSJSONReadingAllowFragments 返回一個任意類型的對象 (既可以是字典也可以是數組或者字符串 只要是 JSON 有效數據片段)
//  將json數據轉化成需要的格式
   ```code
 NSArray *array = [NSJSONSerialization JSONObjectWithData:data options: NSJSONReadingAllowFragments error:nil];
    NSLog(@"array --> %@",array);
for (NSDictionary *dict in array) 
{ 
NSLog(@"dict --> %@",[dict objectForKey:@"content"]);
}   
}````
____
____

- ##JSONKit工具:(第三方工具)
- 首先要引入第三方框架(JSONKit到你的工程)用這個第三方就簡單了許多但是需要引入也是蠻麻煩,有時候還要設置你的編碼,因為JSONKit實在mrc下的可以這樣來改
![JSON解析配置Build Phases](http://upload-images.jianshu.io/upload_images/1523603-be1f0983800f83bc.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


- 解析方法實現(還是比較好記憶的吧)

> ```obj
- (void)touchesBegan:(NSSet<UITouch*> *)touches withEvent:(UIEvent*)event
{      
NSString*path = [[NSBundlemainBundle]pathForResource:@"JSON_stu" ofType:@"txt"];   
NSData*data = [NSDatadataWithContentsOfFile:path];   
//將json數據轉化成需要的格式  
 NSArray*array = [data  objectFromJSONData];     
 NSLog(@"array ---> %@",array);  
 }```


- ##JSON優缺點:

> ##優點: 
1. 數據格式比較簡單,易于讀寫,格式都是壓縮的,占用帶寬小.
2. 易于解析這種語言
3. 支持多種語言,包括ActionScript ,C, C#, ColdFusion, Java, JavaScript, Perl, PHP, Python, Ruby等語言服務器端語言,便于服務器端的解析
4. 因為JSON格式能夠直接為服務器端代碼使用, 大大簡化了服務器端和客戶端的代碼開發量,但是完成的任務不變, 且易于維護.
> ##缺點:
1. 沒有XML格式這么推廣的深入人心和使用廣泛,沒有XML的通用性!
2. JSON格式目前在Web Service中推廣還屬于初級階段
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,345評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,494評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 176,283評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,953評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,714評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,186評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,255評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,410評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,940評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,776評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,976評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,518評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,210評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,642評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,878評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,654評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,958評論 2 373

推薦閱讀更多精彩內容

  • 解析的概念 解析:從事先規定好的格式中提取數據。 解析的前提:提前約定好格式,數據提供方按照格式提供數據,數據獲取...
    逗逗豆豆笑閱讀 1,164評論 2 14
  • JSON JSON和XML都是需要解析的 JSON是一種輕量級的數據格式,一般用于數據交互服務器返回給客戶端的數據...
    JonesCxy閱讀 1,873評論 2 10
  • 在網絡開發中,從服務器獲取的二進制數據包括: > html >圖片 >視頻 >音頻 > zip等 除了以上文件格式...
    小番茄陽陽閱讀 779評論 0 0
  • 在網絡開發中,從服務器獲取的二進制數據包括: > html > 圖片 > 視頻 > 音頻 > zip 等 除了以上...
    方圓十里不留母狗閱讀 796評論 0 0
  • 在工作中,不可避免的我們會頻繁從網絡獲取XML或者Json格式的數據,這些數據有著特定的數據結構,必須對其進行解析...
    Elbert_Z閱讀 935評論 0 2