解析:從事先規(guī)定好的格式中提取數(shù)據(jù)
iOS開發(fā)常見的解析:XML解析合武,JSON解析
XML解析
XMl事例:
<?xml version="1.0" encoding="UTF-8"?>
<!-- 根結(jié)點(diǎn) 是所有節(jié)點(diǎn)的父節(jié)點(diǎn)或者爺節(jié)點(diǎn) -->
<students> <!--開始節(jié)點(diǎn)-->
<!--student的子節(jié)點(diǎn),position就是該節(jié)點(diǎn)的屬性-->
<student position="憤青">
<!--lyj是name節(jié)點(diǎn)的內(nèi)容锥咸,我們可以將該節(jié)點(diǎn)所有的特性都用屬性來表示撼嗓,但是為了閱讀起來方便,我們一般也會(huì)將該節(jié)點(diǎn)的特性用他的子節(jié)點(diǎn)來表示-->
<name>lyj</name>
<age>25</age>
<sex>男</sex>
</student>
<student>
<name>zza</name>
<age>22</age>
<sex>保密</sex>
</student>
</students> <!--結(jié)束節(jié)點(diǎn)-->
XML有兩種解析方法:DOM(Document Object Model)解析和SAX(Simple API for XML)工具
1.SAX解析
SAX基本原理:采用事件驅(qū)動(dòng)解析XML文件欢唾,以流式方式逐行的去讀且警,它不需要解析完整個(gè)文檔,在按內(nèi)容順序解析文檔的過各中礁遣,SAX會(huì)判斷當(dāng)前講到的字符是否合法XML語法中的某部分斑芜,如果符合就觸發(fā)事件(例如startDocument()、endDocument()諸如此類的事件)祟霍,它的特點(diǎn)是不會(huì)記錄前面所碰到的標(biāo)簽杏头,并且它是一個(gè)解析速度快并且占用內(nèi)存少的XML解析器
特點(diǎn):
一.是基于事件驅(qū)動(dòng)的解析方式
二.逐行解析
三.只能讀扔(DOM解析可讀可寫)
四.一般只用做文檔比較大的時(shí)候
//sax解析
-(void)saxPath{
//sax解析:基于事件驅(qū)動(dòng)的解析方式,逐行解析
NSString* xmlPath=[[NSBundle mainBundle] pathForResource:@"xml" ofType:@"xml"];
NSString* xmlStr=[NSString stringWithContentsOfFile:xmlPath encoding:NSUTF8StringEncoding error:nil];
//字符串轉(zhuǎn)data類型
NSData* xmlData=[xmlStr dataUsingEncoding:NSUTF8StringEncoding];
//參數(shù):需要解析的文件內(nèi)容
NSXMLParser* xmlParser=[[NSXMLParser alloc] initWithData:xmlData];
//設(shè)置代理
xmlParser.delegate=self;
//開始解析 同步的過程 當(dāng)整個(gè)解析完成了才會(huì)執(zhí)行下一行代碼
BOOL isSuccess=[xmlParser parse];
if (isSuccess) {
NSLog(@"解析成功");
}else{
NSLog(@"解析失敗");
}
//解析的過程不結(jié)束醇王,就不會(huì)執(zhí)行該打印
NSLog(@"我在解析的最底下");
}
下來遵循協(xié)議呢燥,實(shí)現(xiàn)協(xié)議方法,為了方便獲取數(shù)據(jù)寓娩,聲明一個(gè)字典和數(shù)組
@interface ViewController ()<NSXMLParserDelegate>
@property(nonatomic,strong)NSMutableArray* allDataArray;//存放所有student的節(jié)點(diǎn)
@property(nonatomic,strong)NSMutableDictionary* studentDic;//將student轉(zhuǎn)換為字典
@property(nonatomic,strong)NSString* noteValueString;//存儲(chǔ)節(jié)點(diǎn)中的值
#pragma mark--------parser解析的代理方法
//開始解析整個(gè)文檔了
-(void)parserDidStartDocument:(NSXMLParser *)parser{
NSLog(@"開始解析整個(gè)文檔了");
//初始化外部的可變數(shù)組叛氨,準(zhǔn)備存放student節(jié)點(diǎn)
self.allDataArray=[[NSMutableArray alloc] init];
}
//當(dāng)碰到開始節(jié)點(diǎn)或開始標(biāo)簽的時(shí)候會(huì)執(zhí)行的代理方法
//elementName:標(biāo)簽名稱(節(jié)點(diǎn)名),例如<name>
//namespaceURI:命名空間的標(biāo)識(shí)名 例如<teacher xmlns:l="www.lanou3g.com">
//qName:命名空間的值,就是上面的 www.lanou3g.com
//attributeDict:標(biāo)簽的屬性 例如 <student position="憤青"> position就是標(biāo)簽的屬性棘伴,attributeDict=={pasition:"憤青"}
-(void)parser:(NSXMLParser*)parser didStartElement:(nonnull NSString *)elementName namespaceURI:(nullable NSString *)namespaceURI qualifiedName:(nullable NSString *)qName attributes:(nonnull NSDictionary<NSString *,NSString *> *)attributeDict{
NSLog(@"碰到開始標(biāo)簽----%@",elementName);
//當(dāng)開始解析student節(jié)點(diǎn)的時(shí)候寞埠,說明我們要用到字典了,就需要對(duì)字典進(jìn)行初始化
if ([elementName isEqualToString:@"student"]) {
self.studentDic=[[NSMutableDictionary alloc] init];
}
}
//取出標(biāo)簽中的值
//string:就是標(biāo)簽中的值
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
NSLog(@"正在解析的值為---%@",string);
//將節(jié)點(diǎn)的內(nèi)容存儲(chǔ)起來焊夸,以供節(jié)點(diǎn)解析結(jié)束使用
self.noteValueString=string;
}
//遇到當(dāng)前正在解析標(biāo)簽結(jié)束標(biāo)簽
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
NSLog(@"碰到結(jié)束標(biāo)簽----%@",elementName);
if ([elementName isEqualToString:@"name"]) {
//說明name標(biāo)簽解析結(jié)束
[self.studentDic setObject:self.noteValueString forKey:elementName];
}
if ([elementName isEqualToString:@"age"]) {
//說明age標(biāo)簽解析結(jié)束
[self.studentDic setObject:self.noteValueString forKey:elementName];
}
if ([elementName isEqualToString:@"sex"]) {
//說明sex標(biāo)簽解析結(jié)束
[self.studentDic setObject:self.noteValueString forKey:elementName];
}
if ([elementName isEqualToString:@"student"]) {
//說明一個(gè)student已經(jīng)解析完成仁连,說明一個(gè)字典已經(jīng)完整,應(yīng)該將字典放入數(shù)組中了
[self.allDataArray addObject:self.studentDic];
}
}
//整個(gè)文檔解析結(jié)束
-(void)parserDidEndDocument:(NSXMLParser *)parser{
NSLog(@"整個(gè)文檔解析結(jié)束");
//當(dāng)整個(gè)文檔解析結(jié)束阱穗,說明所有的數(shù)據(jù)我們已經(jīng)拿到饭冬,可以正常使用了
NSLog(@"----%@",self.allDataArray);
}
//當(dāng)解析出錯(cuò)會(huì)調(diào)用的方法
-(void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError{
NSLog(@"解析出現(xiàn)錯(cuò)誤---%@",parseError.description);
}
2.DOM解析
dom解析基于文檔驅(qū)動(dòng)的解析方式,DOM解析XML時(shí),讀入整個(gè)XML文檔并構(gòu)建一個(gè)駐留內(nèi)存的樹結(jié)構(gòu)(節(jié)點(diǎn)樹),通過遍歷樹結(jié)構(gòu)可以檢索任意XML節(jié)點(diǎn),讀取他的屬性和值,而且通常情況下,可以借助XPath,直接查詢XML節(jié)點(diǎn)
使用方法:
1.獲取GDataXMLNode.h/m文件颇象,將GDataXMLNode.h/m文件添加到工程中
2.向工程中增加“l(fā)ibxml2.dylib”動(dòng)態(tài)庫
具體做法 選中整個(gè)工程 在Build Phases的倒數(shù)第二個(gè)選項(xiàng)中點(diǎn)“+”號(hào)伍伤,搜索libxml2.dylib 并添加
3.在工程的“Build Settings”頁中找到“Header Search Path” 點(diǎn)擊添加 "/usr/include/libxml2"
4.導(dǎo)入“GDataXMLNode.h”文件到頭文件 如果工程能編譯通過,說明添加成功
注意:
(1)在工程的Build phases設(shè)置的Link Binary With Libraries里面點(diǎn)擊加號(hào),搜索libxml2.tbd遣钳,選擇添加
(2)在工程的Build Settings設(shè)置里面搜索search扰魂,找到Search paths選項(xiàng)下的Header Search Paths,加入一條/usr/include/libxml2這里三個(gè)反斜杠不能少
(3)在工程的Build Settings設(shè)置里面搜索Other Linker Flags,找到Other Linker Flags蕴茴,雙擊空白處輸入-lxml2
這樣在編譯就不會(huì)報(bào)錯(cuò)啦劝评。??
//dom解析 基于文檔驅(qū)動(dòng)的解析方式
-(void)domParser{
//需要獲取解析的源文件
NSString* xmlPath=[[NSBundle mainBundle] pathForResource:@"xml" ofType:@"xml"];
NSString* xmlStr=[NSString stringWithContentsOfFile:xmlPath encoding:NSUTF8StringEncoding error:nil];
//字符串轉(zhuǎn)data類型
NSData* xmlData=[xmlStr dataUsingEncoding:NSUTF8StringEncoding];
//dom解析
//step1:將源xml文件轉(zhuǎn)換成樹狀結(jié)構(gòu)的文檔放在內(nèi)存中,以供遍歷獲取每個(gè)節(jié)點(diǎn)
GDataXMLDocument* xmlDoc=[[GDataXMLDocument alloc] initWithData:xmlData encoding:NSUTF8StringEncoding error:nil];
//step2:獲取根節(jié)點(diǎn) 就相當(dāng)于獲取到了students節(jié)點(diǎn)
GDataXMLElement* rootElement=[xmlDoc rootElement];
//step3:獲取我們需要的子節(jié)點(diǎn)
//參數(shù):我們需要獲取的標(biāo)簽名
// NSArray* studentArray=[rootElement elementsForName:@"student"];
//初始化一個(gè)可變數(shù)組倦淀,準(zhǔn)備存放所有的student轉(zhuǎn)換成的字典
NSMutableArray* allStudentsArray=[[NSMutableArray alloc] init];
//添加節(jié)點(diǎn)(向現(xiàn)有的文檔動(dòng)態(tài)的增加一個(gè)student節(jié)點(diǎn))
//節(jié)點(diǎn)創(chuàng)建 <student></student>
GDataXMLElement* studentElement = [GDataXMLElement elementWithName:@"student"];
//將student節(jié)點(diǎn)加入到它的父節(jié)點(diǎn)中
// [rootElement addChild:studentElement];
//為student增加子節(jié)點(diǎn)
GDataXMLElement* nameElement = [GDataXMLElement elementWithName:@"name" stringValue:@"ze an"];
GDataXMLElement* ageElement = [GDataXMLElement elementWithName:@"age" stringValue:@"23"];
GDataXMLElement* genderElement = [GDataXMLElement elementWithName:@"gender" stringValue:@"未知"];
[studentElement addChild:nameElement];
[studentElement addChild:ageElement];
[studentElement addChild:genderElement];
[rootElement addChild:studentElement];
NSArray* studentArray=[rootElement elementsForName:@"student"];
//step4:遍歷數(shù)組
//stuNode:對(duì)應(yīng)一個(gè)student節(jié)點(diǎn)
/*<student>
<name></name>
<age></age>
<sex></sex>
</student>
*/
//每執(zhí)行一次循環(huán)體蒋畜,就相當(dāng)于獲取了一個(gè)完整的student節(jié)點(diǎn),結(jié)構(gòu)如上
// for (GDataXMLElement* stuelement in studentArray) {
// //初始化一個(gè)字典
// NSMutableDictionary* studentDic=[[NSMutableDictionary alloc] init];
//// NSString* name=[[[stuelement elementsForName:@"name"] firstObject] stringValue];
// //獲取name節(jié)點(diǎn)
// GDataXMLElement* nameElement=[stuelement elementsForName:@"name"].firstObject;
// //取出節(jié)點(diǎn)中的值
// NSString* name=[nameElement stringValue];
// //將name的值放入字典中
// [studentDic setObject:name forKey:@"name"];
//
// //獲取age節(jié)點(diǎn)
// GDataXMLElement* ageElement=[stuelement elementsForName:@"age"].firstObject;
// NSString* age=[ageElement stringValue];
// [studentDic setObject:age forKey:@"age"];
//
// //獲取sex節(jié)點(diǎn)
// GDataXMLElement* sexElement=[stuelement elementsForName:@"sex"].firstObject;
// NSString* sex=[sexElement stringValue];
// [studentDic setObject:sex forKey:@"sex"];
// //將字典放入數(shù)組中
// [allStudentsArray addObject:studentDic];
// }
// NSLog(@"----%@",allStudentsArray);
for (GDataXMLElement* studentNode in studentArray) {
//遍歷獲取student所有的子節(jié)點(diǎn)
NSArray* subStudentNode=[studentNode children];
NSMutableDictionary* studentDic=[[NSMutableDictionary alloc] init];
for (GDataXMLElement* subOfStudentNode in subStudentNode) {
//獲取子節(jié)點(diǎn)的名稱
NSString* noteName=[subOfStudentNode name];
//獲取節(jié)點(diǎn)內(nèi)容
NSString* noteValue=[subOfStudentNode stringValue];
[studentDic setObject:noteValue forKey:noteName];
}
// 將字典加入到數(shù)組中
[allStudentsArray addObject:studentDic];
}
NSLog(@"----%@",allStudentsArray);
}
3.JSON解析
//json解析
-(void)jsonParser{
//獲取要解析的json源文件
NSString* jsonPath=[[NSBundle mainBundle] pathForResource:@"DemoJson" ofType:@"json"];
NSString* jsonStr=[NSString stringWithContentsOfFile:jsonPath encoding:NSUTF8StringEncoding error:nil];
//字符串轉(zhuǎn)data類型
NSData* jsonData=[jsonStr dataUsingEncoding:NSUTF8StringEncoding];
//json解析
NSDictionary* dic= [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingAllowFragments error:nil];
NSLog(@"---%@",dic);
}