解析XML文件的兩種方式 SAX和DOM

一、數據解析

  1. 解析的基本概念
  • 所謂「解析」:從事先規定好的格式中提取數據
  • 解析的前提:提早約定好格式,數據提供方按照格式提供數據、數據獲取方則按照格式獲取數據
  • iOS開發常見的解析:XML解析、JSON解析

二、XML數據結構

  • XML:Extensible Markup language(可擴展標記語言),主流數據格式之一,能夠用來存儲和傳輸數據。
  • XML數據格式的功能
    • 數據交換
    • 內容管理
    • 用做配置文件
  • XML數據結構的語法
    • 聲明
    • 節點使用一對標籤表示:起始和結束標籤。
    • 根節點是起始節點,只有一個,節點能夠嵌套。
    • 節點能夠有值,存儲在一對兒標籤中。
  • XML示例

 

三、JSON數據結構

  • JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式。JSON採用徹底獨立於語言的文本格式,易於閱讀和編寫,同時也易於機器解析和生成。這些特性使JSON成爲理想的數據交換語言。
  • JSON數據結構的語法
    • JSON文件有兩種結構:
    • 對象:「名稱/值」對的集合。不一樣的語言中,它被理解爲對象,記錄,結構,字典,哈希表,有鍵列表,或者關聯數組。以「{」開始,以「}」結束,是「名稱/值」對的集合。名稱和值中間用「:」隔開。多個「名稱/值」對之間用「,」隔開。
    • 數組: 值的有序列表。在大部分語言中,它被理解爲數組。以「[」開始,以「]」結束,中間是數據。數據以「,」分隔。
    • JSON中的數據類型:字符串、數值、BOOL、對象、數組。
  • JSON示例
  • JSON數據結構的功能
    • 數據交換
    • 內容管理  
    • 配置文件

四、XML與JSON兩種數據結構的優缺點

  • XML優缺點
    • 優勢:

      • 格式統一,符合標準。
      • 容易與其餘系統進行遠程交互, 數據共享比較方便。
    • 
缺點:
      • XML文件格式文件龐大,格式複雜, 傳輸佔用帶寬。

      • 服務器端和客戶端都須要花費大量代碼來解析XML,不論服務器端仍是客戶端都使代碼變的異常複雜和不容易維護。

      • 客戶端不一樣瀏覽器之間解析XML的方式不一致,須要重複編寫不少代碼。

      • 服務器端和客戶端解析XML花費資源和時間。
  • JSON優缺點
    • 優勢:
      • 
 數據格式比較簡單,易於讀寫,格式都是壓縮的,佔用帶寬小。
      • 
易於解析這種語言。
      • 支持多種語言,包括ActionScript,C,C#,ColdFusion,Java,JavaScript,Perl,PHP,Python,Ruby等語言服務器端語言,便於服務器端的解析。

      • 由於JSON格式可以直接爲服務器端代碼使用,大大簡化了服務器端和客戶端的代碼開發量,可是完成的任務不變,且易於維護。
    • 

缺點:

      • 沒有XML格式這麼推廣的深刻人心和使用普遍,沒有XML那麼通用性。

      • JSON格式目前在Web Service中推廣還屬於初級階段 。

 

五、SAX解析XML文件

  解析的XML文件json

  StudentInformation_XML.txt數組

複製代碼
 1 <students>
 2     <student>
 3         <name>小暖心</name>
 4         <gender>女</gender>
 5         <age>18</age>
 6         <hobby>傲然</hobby>
 7     </student>
 8     <student>
 9         <name>MBBoy</name>
10         <gender>男</gender>
11         <age>20</age>
12         <hobby>借牙籤</hobby>
13     </student>
14     <student>
15         <name>海</name>
16         <gender>男</gender>
17         <age>16</age>
18         <hobby>助人爲樂</hobby>
19     </student>
20     <student>
21         <name>-1</name>
22         <gender>男</gender>
23         <age>69</age>
24         <hobby>芳芳女神</hobby>
25     </student>
26     <student>
27         <name>yyp</name>
28         <gender>女</gender>
29         <age>18</age>
30         <hobby>學習</hobby>
31     </student>
32 </students>
複製代碼

 

  

SAX:Simple API for XML 。 基於事件驅動的解析方式,逐行解析數據(採用協議回調機制)xcode

  • 核心類:NSXMLParser是iOS自帶的XML解析類,採用SAX方式解析數據。
  • 解析過程有NSXMLParserDelegate協議方法回調
  • 解析過程:開始標籤->取值->結束標籤->取值

  使用NSXMLParse要先建立它,設置各類屬性,主要用到一下幾個方法:
      瀏覽器

  

   

  SAM解析XML數據步驟服務器

複製代碼
 1 #pragma mark - sax解析XML文件
 2 - (IBAction)saxParserActionXMLDocument:(UIButton *)sender {
 3     // 1.獲取文件路徑
 4     NSString *filePath = [[NSBundle mainBundle] pathForResource:@"StudentInformation_XML" ofType:@"txt"];
 5     // 2.將文件轉換成NSData類型的對象
 6     NSData *data = [NSData dataWithContentsOfFile:filePath];
 7 //    NSLog(@"%@",data);
 8     // 3.設置SAX解析,並關聯相關的XML文件
 9     NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
10     // 4.設置代理
11     parser.delegate = self;
12     // 5.開始解析
13     [parser parse];
14 }
15 
16 #pragma mark - NSXMLParserDelegate的協議方法
17 #pragma mark - 1.文檔解析
18 - (void)parserDidStartDocument:(NSXMLParser *)parser {
19     // 數組初始化
20     self.dataArray = [NSMutableArray array];
21 }
22 
23 #pragma mark - 2.開始標籤解析
24 - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict {
25     // 根據需求須要的標籤去獲取相關的數據
26     if ([elementName isEqualToString:@"student"]) {
27         Student *student = [[Student alloc] init];
28         // 在這裏不須要賦值
29         // 將數據對象添加到數組中
30         [self.dataArray addObject:student];
31     }
32     // 將當前的標籤值傳給currentElement屬性
33     self.currentElement = elementName;
34 }
35 
36 #pragma mark - 3.解析標籤中的內容,給對象賦值
37 - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
38     // 從數組中取出相關的student對象,每次從數組中去最後一個元素,保證每次取出的對象都是剛剛存入的對象
39     Student *student = [self.dataArray lastObject];
40     // KVC賦值
41     [student setValue:string forKey:self.currentElement];
42 }
43 
44 #pragma mark - 4.結束標籤
45 - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
46     self.currentElement = nil;
47 }
48 
49 #pragma mark - 5.結束文檔解析
50 - (void)parserDidEndDocument:(NSXMLParser *)parser {
51     // 打印校驗
52     for (Student *student in self.dataArray) {
53         NSLog(@"name = %@, gender = %@, age = %ld, hobby = %@", student.name, student.gender, student.age, student.hobby);
54     }
55 }
56 
57 #pragma mark - 6.查看相關的錯誤處理
58 - (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
59     NSLog(@"錯誤信息error = %@", parseError);
60 }
複製代碼

六、DOM解析XML文件(第三方類:GDataXMLNote.h/m)

DOM:Document Object Model(文檔對象模型)。DOM方式解析XML時,讀入整個XML文檔並構建一個駐留內存的樹結構(節點樹),經過遍歷樹結構能夠檢索任意XML節點,讀取它的屬性和值。並且一般狀況下,能夠藉助XPath,直接查詢XML節點。數據結構

  • 採用DOM方式解析數據
  • iOS中包含一個C語言的動態連接庫libxml2.dylib(xcode7之後改成libxml2.tbd),解析速度比NSXMLParser快。
  • GDataXMLNode是Google提供的開源XML解析類,對libxml2.tbd進行了Objective-C的封裝,能對較小或中等的xml文檔進行讀寫操做且支持XPath語法。

  GDataXMLElement類的用到的屬性和方法
  框架

  GDataXMLNote解析XML文件步驟dom

  1. 獲取GDataXMLNode.h/m文件,將GDataXMLNode.h/m文件添加到工程中。
  2. 向工程中增長「libxml2.dylib」動態庫。


  3. 導入"GDataXMLNode.h"文件到頭文件中,此時編譯失敗,而後在工程的"Build Settings"頁中找到"Header Search Path"項,添加"/usr/include/libxml2"。在"Other Linker Flags"項,添加"-lxml2"


  4. 此時編譯報錯,GDataXMLNote是非ARC文件,運行在ARC環境下會報錯,按以下步驟,在Compile Source裏找到剛引入的GDataXMLNote.m文件,添加"-fno-objc-arc"
複製代碼
 1 #pragma mark - ---------------------------------------------
 2 #pragma mark - DOM解析XML文件
 3 - (IBAction)domParserActionXMLDocument:(UIButton *)sender {
 4     // 1.引入libxml2.tbd動態庫
 5     // 2.引入第三方GDataXMLNode
 6     // 3.獲取文件路徑
 7     NSString *filePath = [[NSBundle mainBundle] pathForResource:@"StudentInformation_XML" ofType:@"txt"];
 8     // 4.根據路徑獲取NSData類型的數據
 9     NSData *data = [NSData dataWithContentsOfFile:filePath];
10     // 4.5 初始化數組
11     self.dataArray = [NSMutableArray array];
12     // 5.設置DOM解析,建立GDataXMLDocument對象,此時XML文件內全部的節點以樹的形式存在GDataXMLDocument
13     GDataXMLDocument *document = [[GDataXMLDocument alloc] initWithData:data options:0 error:nil];
14     // 6.獲取根節點,根節點裏麪包含了XML的全部信息
15     GDataXMLElement *rootElement = document.rootElement;
16     // 7.遍歷獲取相對應的子節點(student)
17     for (GDataXMLElement *studentElement in rootElement.children) {
18         Student *student = [[Student alloc] init];
19         // 遍歷子節點(student)的子節點(name,gender,age,hobby)
20         for (GDataXMLElement *element in studentElement.children) {
21             NSLog(@"%@",element);
22             // KVC:根據標籤給student對象賦值
23             // element.name 標籤的名字
24             // element.stringValue 標籤的值
25             [student setValue:element.stringValue forKey:element.name];
26         }
27         // 將student對象添加到數組中
28         [self.dataArray addObject:student];
29     }
30     // 遍歷檢驗
31     for (Student *student in self.dataArray) {
32         NSLog(@"name = %@, gender = %@, age = %ld, hobby = %@", student.name, student.gender, student.age, student.hobby);
33     }
34 }
複製代碼

 


  解析的JSON文件  工具

  StudentInformation_json.txt學習

複製代碼
 1 [
 2     {
 3         "name":"凱凱",
 4         "gender":"男",
 5         "age":"18",
 6         "hobby":"PS"
 7     },
 8     {
 9         "name":"YH",
10         "gender":"男",
11         "age":"20",
12         "hobby":"女"
13     },
14     {
15         "name":"ZF",
16         "gender":"男",
17         "age":"20",
18         "hobby":"玩毛"
19     },
20     {
21         "name":"小明",
22         "gender":"男",
23         "age":"22",
24         "hobby":"滾出去"
25     },
26     {
27         "name":"淮予",
28         "gender":"女",
29         "age":"21",
30         "hobby":"小暖心"
31     }
32 ]
複製代碼

 

七、系統自帶Foundation框架解析JSON數據

  NSJSONSerialization  裏面包含了兩個方法來經過不一樣數據形式解析JSON數據。

    

複製代碼
 1 #pragma mark - ---------------------------------------------------
 2 #pragma mark - 系統自帶Foundation框架解析JSON數據
 3 - (IBAction)foundationParserActionJSONDocument:(UIButton *)sender {
 4     // 1.獲取文件路徑
 5     NSString *filePath = [[NSBundle mainBundle] pathForResource:@"StudentInformation_json" ofType:@"txt"];
 6     // 2.根據路徑獲取NSData類型的數據
 7     NSData *data = [NSData dataWithContentsOfFile:filePath];
 8     // 2.5 初始化數組
 9     self.dataArray = [NSMutableArray array];
10     // 3.解析
11     NSArray *resultArray = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
12     // 4.遍歷數組,使用KVC給Student對象賦值
13     for (NSDictionary *dict in resultArray) {
14         Student *student = [[Student alloc] init];
15         [student setValuesForKeysWithDictionary:dict];
16         [self.dataArray addObject:student];
17     }
18     // 遍歷檢驗
19     for (Student *student in self.dataArray) {
20         NSLog(@"name = %@, gender = %@, age = %ld, hobby = %@", student.name, student.gender, student.age, student.hobby);
21     }
22 }
複製代碼

 

八、使用第三方類JSONKit來解析JSON數據

  引入JSONKit.h/m文件,並設置非ARC文件在ARC環境下運行。

  

複製代碼
 1  1 #pragma mark - -------------------------------------------------
 2  2 #pragma mark - 使用第三方類JSONKit來解析JSON數據
 3  3 - (IBAction)jsonkitParserActionJSONDocument:(UIButton *)sender {
 4  4     // 1.引入第三方類  -- 設置 非arc文件在arc環境下運行
 5  5     // 2.獲取文件路徑
 6  6     NSString *filePath = [[NSBundle mainBundle] pathForResource:@"StudentInformation_json" ofType:@"txt"];
 7  7     // 3.根據路徑獲取NSData類型的數據
 8  8     NSData *data = [NSData dataWithContentsOfFile:filePath];
 9  9     // 3.5初始化數組
10 10     self.dataArray = [NSMutableArray array];
11 11     // 4. 解析   與NSJSONSerialization解析的惟一差異
12 12     NSArray *resultArray = [data objectFromJSONData];
13 13     // 5.遍歷數組,使用KVC給Student對象賦值
14 14     for (NSDictionary *dict in resultArray) {
15 15         Student *student = [[Student alloc] init];
16 16         [student setValuesForKeysWithDictionary:dict];
17 17         [self.dataArray addObject:student];
18 18     }
19 19     // 遍歷檢驗
20 20     for (Student *student in self.dataArray) {
21 21         NSLog(@"name = %@, gender = %@, age = %ld, hobby = %@", student.name, student.gender, student.age, student.hobby);
22 22     }
23 23 }
複製代碼

總結:

  1.數據解析:從某種格式的數據中提取本身所須要的數據  2.主流的數據交換格式有兩種:XML和JSON  3.XML解析分爲兩種:SAX解析和DOM解析  4.XML解析工具:NSXMLParser、GDataXMLNode、TochXML和KissXML等    5.JSON解析工具:JSONKit、NSJSONSerialization、TouchJSON和SBJSON等,其中NSJSONSerialization是系統提供的解析類,其解析效率是最高的

相關文章
相關標籤/搜索