iOS – XML解析

Sheffi發表於2019-03-04

前些日子,看到一個同學在問xml解析的問題,自己也對xml解析瞭解不是很多,都是用了jsno解析。別去學習了一下xml解析。
在收xml解析之前,首先先簡單說一下xml的基本語法。
XML :是Extensible Markup Language的簡寫,全名叫做可擴充套件標記語言。
簡單的語法如下:

iOS – XML解析
這裡寫圖片描述

iOS – XML解析
這裡寫圖片描述

iOS – XML解析
這裡寫圖片描述

示例:
需求:北京 晴 最高溫度15℃ 最低溫度5℃
XML實現:


複製程式碼

另一種實現方式:


  北京
  
  15
  5
複製程式碼

以上就是簡單的xml的基本語法。下面開始說iOS中xml的解析的事。
關於XML,有兩種解析方式,分別是SAX(Simple API for XML,基於事件驅動的解析方式,逐行解析資料,採用協議回撥機制)和DOM(Document Object Model ,文件物件模型。解析時需要將XML檔案整體讀入,並且將XML結構化成樹狀,使用時再通過樹狀結構讀取相關資料,查詢特定節點,然後對節點進行讀或寫)。蘋果官方原生的NSXMLParse類庫採用第一種方式,即SAX方式解析XML,它基於事件通知的模式,一邊讀取文件一邊解析資料,不用等待文件全部讀入以後再解析,所以如果你正列印解析的資料,而解析過程中間出現了錯誤,那麼在錯誤節點之間的資料會正常列印,錯誤後面的資料不會被列印。解析過程由NSXMLParserDelegate協議方法回撥。在這裡,我們主要講iOS原生的解析方式,就是使用NSXMLParserDelegate協議方法回撥。
首先使用這個瞭解這個協議的代理方法:

//準備解析
-(void)parserDidStartDocument:(NSXMLParser *)parser;
//準備解析當前節點
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict;
//獲取首尾節點間內容
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string;
//解析完當前節點
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName;
//解析結束
-(void)parserDidEndDocument:(NSXMLParser *)parser;複製程式碼

簡單介紹完代理後,進行寫demo。
解析第一個xml的:James
擼程式碼:

- (IBAction)onParse:(id)sender {
    NSString *xmlStr1 = @"James";
    NSData *xmlData = [xmlStr1 dataUsingEncoding:NSUTF8StringEncoding];
    //初始化NSXMLParser,並遵循協議
    NSXMLParser *xmlParaser = [[NSXMLParser alloc]initWithData:xmlData];
    xmlParaser.delegate = self;
    //開始解析
    [xmlParaser parse];
}
//準備解析
-(void)parserDidStartDocument:(NSXMLParser *)parser{
    _label.text = [_label.text stringByAppendingString:@"準備解析"];
    _label.text = [_label.text stringByAppendingString:@"
"];
}
//準備解析當前節點
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
    _label.text = [_label.text stringByAppendingString:@"準備解析當前節點"];
    _label.text = [_label.text stringByAppendingString:@"
"];
}
//獲取首尾節點間內容
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
    _label.text = [_label.text stringByAppendingString:string];
    _label.text = [_label.text stringByAppendingString:@"
"];
}
//解析完當前節點
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
    _label.text = [_label.text stringByAppendingString:@"解析完當前節點"];
    _label.text = [_label.text stringByAppendingString:@"
"];
}
//解析結束
-(void)parserDidEndDocument:(NSXMLParser *)parser{
    _label.text = _label.text = [_label.text stringByAppendingString:@"解析結束"];
    _label.text = [_label.text stringByAppendingString:@"
"];
}
@end複製程式碼

執行結果:

iOS – XML解析
這裡寫圖片描述

第二個例子:解析:
直接擼程式碼:

- (IBAction)onParse:(id)sender {
//    NSString *xmlStr1 = @"James";
    NSString *xmlStr2 = @"";
    NSData *xmlData = [xmlStr2 dataUsingEncoding:NSUTF8StringEncoding];
    NSXMLParser *xmlParaser = [[NSXMLParser alloc]initWithData:xmlData];
    xmlParaser.delegate = self;
    [xmlParaser parse];
}
//準備解析
-(void)parserDidStartDocument:(NSXMLParser *)parser{
    _label.text = [_label.text stringByAppendingString:@"準備解析"];
    _label.text = [_label.text stringByAppendingString:@"
"];
}
//準備解析當前節點
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
    _label.text = [_label.text stringByAppendingString:@"準備解析當前節點"];
    _label.text = [_label.text stringByAppendingString:elementName];
    _label.text = [_label.text stringByAppendingString:@"
"];
    _label.text = [_label.text stringByAppendingString:[attributeDict objectForKey:@"name"]];
    _label.text = [_label.text stringByAppendingString:@"
"];
}
//獲取首尾節點間內容
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
    _label.text = [_label.text stringByAppendingString:@"獲取首尾節點間內容"];
    _label.text = [_label.text stringByAppendingString:@"
"];
}
//解析完當前節點
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
    _label.text = [_label.text stringByAppendingString:@"解析完當前節點"];
    _label.text = [_label.text stringByAppendingString:@"
"];
}
//解析結束
-(void)parserDidEndDocument:(NSXMLParser *)parser{
    _label.text = _label.text = [_label.text stringByAppendingString:@"解析結束"];
    _label.text = [_label.text stringByAppendingString:@"
"];
}
@end複製程式碼

執行結果:

iOS – XML解析
這裡寫圖片描述

另一種的解析,可以使用GDataXML第三方進行解析。這裡不再詳細說。

最後總結:
xml兩種解析SAX和DOM,各有優勢,比如在應對比較大資料量的XML檔案時,後者由於需要先讀取整個文件,效能和速度上就必然不及前者了。解析小資料量的時候使用DMO更加高效,大家可以根據資料量的多少進行合理選擇。

以上就是xml的簡單解析。再次感謝慕課網(www.imooc.com/)。
以上如有錯誤,請指出,非常感謝。

微信公眾號:不靠譜程式猿 微信公眾號:Sheffi_Programmer
Github:Sheffi(github.com/goingmyway1…
新浪微博:Sheffi567
掘金:Sheffi(gold.xitu.io/user/57c137…
部落格地址:blog.csdn.net/qq_34195670…