XML數(shù)據(jù)解析

一、什么是XML

  1. 全稱是ExtensibleMarkupLanguage,譯作“可擴展標(biāo)記語言”
  2. 跟JSON一樣,也是常用的一種用于交互的數(shù)據(jù)格式
  3. 一般也叫XML文檔(XML Document)
  • XML舉例
<videos>
   <videoname="小黃人第01部"length="30"/>
   <videoname="小黃人第02部"length="19"/>
   <videoname="小黃人第03部"length="33"/></videos>

二、XML語法

一個常見的XML文檔一般由以下部分組成

  • 文檔聲明
  • 元素(Element)
  • 屬性(Attribute)

1、XML語法 – 文檔聲明

在XML文檔的最前面,必須編寫一個文檔聲明,用來聲明XML文檔的類型

  • 最簡單的聲明
    <?xml version="1.0" ?>

  • encoding屬性說明文檔的字符編碼
    <?xml version="1.0" encoding="UTF-8" ?>

2、XML語法 – 元素(Element)

  • 一個元素包括了開始標(biāo)簽和結(jié)束標(biāo)簽

  • 擁有內(nèi)容的元素:<video>小黃人</video>

  • 沒有內(nèi)容的元素:<video></video>

  • 沒有內(nèi)容的元素簡寫:<video/>

  • 一個元素可以嵌套若干個子元素(不能出現(xiàn)交叉嵌套)

<videos>
    <video>
        <name>小黃人 第01部</name>
         <length>30</length>
    </video>
</videos>
  • 規(guī)范的XML文檔最多只有1個根元素,其他元素都是根元素的子孫元素
XML語法 –元素的注意

XML中的所有空格和換行,都會當(dāng)做具體內(nèi)容處理

● 下面兩個元素的內(nèi)容是不一樣的

第1個

<video>小黃人</video>

第2個

<video>
    小黃人
</video>

3、XML語法 – 屬性(Attribute)

  • 一個元素可以擁有多個屬性
    <video name="小黃人 第01部" length="30" />
  1. video元素擁有name和length兩個屬性
  2. 屬性值必須用 雙引號"" 或者 單引號'' 括住
  • 實際上,屬性表示的信息也可以用子元素來表示,比如
<video>
    <name>小黃人 第01部</name>
        <length>30</length>
</video>

4、XML解析

  • 要想從XML中提取有用的信息,必須得學(xué)會解析XML

1、提取name元素里面的內(nèi)容
<name>小黃人 第01部</name>
2、提取video元素中name和length屬性的值
<video name="小黃人 第01部" length="30" />

  • XML的解析方式有2種

1、DOM:一次性將整個XML文檔加載進內(nèi)存,比較適合解析小文件
2、SAX:從根元素開始,按順序一個元素一個元素往下解析,比較適合解析大文件

三、iOS中的XML解析

  • 在iOS中,解析XML的手段有很多

1、 蘋果原生
** NSXMLParser**:SAX方式解析,使用簡單

2、第三方框架
** libxml2:純C語言,默認包含在iOS SDK中,同時支持DOMSAX方式解析
** GDataXML
DOM方式解析,由Google開發(fā),基于libxml2

3、 XML解析方式的選擇建議

 **大文件:NSXMLParser、libxml2**
 **小文件:GDataXML、NSXMLParser、libxml2**

四、NSXMLParser

使用步驟

// 傳入XML數(shù)據(jù),創(chuàng)建解析器
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
// 設(shè)置代理,監(jiān)聽解析過程
parser.delegate = self;
// 開始解析
[parser parse];
  • NSXMLParser采取的是SAX方式解析,特點是事件驅(qū)動,下面情況都會通知代理
  • 當(dāng)掃描到文檔(Document)的開始與結(jié)束
  • 當(dāng)掃描到元素(Element)的開始與結(jié)束

NSXMLParserDelegate

  • 當(dāng)掃描到文檔的開始時調(diào)用(開始解析)
    - (void)parserDidStartDocument:(NSXMLParser *)parser

  • 當(dāng)掃描到文檔的結(jié)束時調(diào)用(解析完畢)
    - (void)parserDidEndDocument:(NSXMLParser *)parser

  • 當(dāng)掃描到元素的開始時調(diào)用(attributeDict存放著元素的屬性)
    - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict

  • 當(dāng)掃描到元素的結(jié)束時調(diào)用
    - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName

代碼如下:

/*TableView的數(shù)據(jù)源*/(將解析出來的模型放在這里)
@property (nonatomic, strong) NSMutableArray *videos;
@end

@implementation ViewController

// 進行懶加載
-(NSMutableArray *)videos
{
    if (_videos == nil) {
        _videos = [NSMutableArray array];
    }
    return _videos;
}

        //4.1   創(chuàng)建解析器Sax
        NSXMLParser *parser = [[NSXMLParser alloc]initWithData:data];
       
        //4.2   設(shè)置代理
        parser.delegate = self;
       
        //4.3   開始解析(調(diào)用這個方法,代表開始解析)
        [parser parse];
       
        //5.刷新TableView(全部解析完,才會刷新)
        [self.tableView reloadData];

#pragma mark  NSXMLParserDelegate  start

/*
 1.開始解析XML文檔
 */
-(void)parserDidStartDocument:(NSXMLParser *)parser
{
     NSLog(@"parserDidStartDocument");
}

/*
 2.解析XML文檔中的每一個元素,會調(diào)用多次
 */
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict
{
//      NSLog(@"didStartElement");
    NSLog(@"%@---%@",elementName,attributeDict); // 元素名稱和屬性字典
   
// 第一種方法(利用keyValues屬性)
    XMGVideo *video = [[XMGVideo alloc] init];
    video.keyValues = attributeDict;
    [self.videos addObject:video];

//  第二種方法
//    [XMGVideo objectWithKeyValues:attributeDict];   // 字典轉(zhuǎn)換成模型
//    [self.videos addObject:[XMGVideo objectWithKeyValues:attributeDict]];    

}

/*
 3.解析XML文檔中的每一個元素結(jié)束
 */
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
//     NSLog(@"didEndElement");
}

/*
 4.整個XML文檔都已經(jīng)解析完成
 */
-(void)parserDidEndDocument:(NSXMLParser *)parser
{
    NSLog(@"parserDidEndDocument");
}
#pragma mark  NSXMLParserDelegate  end

五、GDataXML

1、GDataXML配置

GDataXML基于libxml2庫,得做以下配置
1、導(dǎo)入libxml2庫


1.png

2、設(shè)置libxml2的頭文件搜索路徑(為了能找到libxml2庫的所有頭文件)

Head Search Path中加入/usr/include/libxml2

Snip20151009_312.png

3、設(shè)置鏈接參數(shù)(自動鏈接libxml2庫)

在Other Linker Flags中加入-lxml2

Snip20151009_313.png

4、由于GDataXML是非ARC的,因此得設(shè)置編譯參數(shù)

2.png

2、GDataXML使用

  • GDataXML中常用的類
    • GDataXMLDocument:代表整個XML文檔
    • GDataXMLElement
      ? 代表文檔中的每個元素
      ? 使用attributeForName:方法可以獲得屬性值
 //1.確定請求路徑   
 NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/video?type=XML"];      

 //2.創(chuàng)建請求對象   
 NSURLRequest *request = [NSURLRequest requestWithURL:url];   
   
 //3.發(fā)送異步請求   
 [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {             
         //4.解析數(shù)據(jù)       
         //4.1 加載整個XML文檔        
         GDataXMLDocument *doc  = [[GDataXMLDocument alloc]initWithData:data options:kNilOptions error:nil];               
         //4.2 拿到根元素      
          NSArray *eles =  [doc.rootElement elementsForName:@"video"];        
         //4.3 取出每個子元素的屬性并轉(zhuǎn)換為模型
          for (GDataXMLElement *ele in eles) {     
                NSLog(@"%@",ele);            
                XMGVideo *video = [[XMGVideo alloc] init];                       
                video.name = [ele attributeForName:@"name"].stringValue;  // 返回的類型不一致,轉(zhuǎn)換成字符串          
                video.length = [ele attributeForName:@"length"].stringValue.integerValue;    
                video.image = [ele attributeForName:@"image"].stringValue; 
                video.url = [ele attributeForName:@"url"].stringValue;
                //4.4 將轉(zhuǎn)換好的模型添加到tableview的數(shù)據(jù)源self.videos數(shù)組中
                [self.videos addObject:video];
            }
         //5.刷新TableView
         [self.tableView reloadData];        
    }];

JSON和XML比較

同一份數(shù)據(jù),既可以用JSON來表示,也可以用XML來表示


4.png

相比之下,JSON的體積小于XML,所以服務(wù)器返回給移動端的數(shù)據(jù)格式以JSON居多

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 使用NSURLConnection來請求數(shù)據(jù) JSON數(shù)據(jù)的請求 現(xiàn)在大多情況下都使用三方框架來完成的 l在iOS...
    iamgaoshuai閱讀 672評論 0 1
  • XML簡單介紹 什么是XMLXML:可擴展標(biāo)記語言a.語法b.XML文檔的三部分(聲明、元素和屬性)c.其它注意點...
    Mario_ZJ閱讀 515評論 0 2
  • JSON 1.JSON是一種輕量級的數(shù)據(jù)格式,一般都是用于數(shù)據(jù)交互2.服務(wù)器返回給客戶端的數(shù)據(jù),一般都是JSON格...
    Little_Dragon閱讀 1,552評論 0 5
  • JSON JSON和XML都是需要解析的 JSON是一種輕量級的數(shù)據(jù)格式,一般用于數(shù)據(jù)交互服務(wù)器返回給客戶端的數(shù)據(jù)...
    JonesCxy閱讀 2,008評論 2 10
  • XML的解析方式有2種 DOM:一次性將整個XML文檔加載進內(nèi)存,比較適合解析小文件 SAX:從根元素開始,按順序...
    LiwaySun閱讀 244評論 0 1

友情鏈接更多精彩內(nèi)容