-
解析的基本概念
- 解析: 從事先規定好的格式中提取數據
- 解析的前提: 提前約定好格式,數據提供方按照格式提供數據,數據獲取方則按照格式獲取數據 OS開發常見的解析: XML解析,JSON解析
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, 對象,數組

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

- ##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下的可以這樣來改

- 解析方法實現(還是比較好記憶的吧)
> ```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中推廣還屬于初級階段