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

一癣丧、什么是XML

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

二帘营、XML語(yǔ)法

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

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

1尉姨、XML語(yǔ)法 – 文檔聲明

在XML文檔的最前面并级,必須編寫一個(gè)文檔聲明拂檩,用來(lái)聲明XML文檔的類型

  • 最簡(jiǎn)單的聲明
    <?xml version="1.0" ?>

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

2、XML語(yǔ)法 – 元素(Element)

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

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

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

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

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

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

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

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

第1個(gè)

<video>小黃人</video>

第2個(gè)

<video>
    小黃人
</video>

3、XML語(yǔ)法 – 屬性(Attribute)

  • 一個(gè)元素可以擁有多個(gè)屬性
    <video name="小黃人 第01部" length="30" />
  1. video元素?fù)碛衝ame和length兩個(gè)屬性
  2. 屬性值必須用 雙引號(hào)"" 或者 單引號(hào)'' 括住
  • 實(shí)際上呀潭,屬性表示的信息也可以用子元素來(lái)表示钉迷,比如
<video>
    <name>小黃人 第01部</name>
        <length>30</length>
</video>

4、XML解析

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

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

  • XML的解析方式有2種

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

三、iOS中的XML解析

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

1塌鸯、 蘋果原生
** NSXMLParser**:SAX方式解析,使用簡(jiǎn)單

2唐片、第三方框架
** libxml2:純C語(yǔ)言丙猬,默認(rèn)包含在iOS SDK中,同時(shí)支持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)聽解析過(guò)程
parser.delegate = self;
// 開始解析
[parser parse];
  • NSXMLParser采取的是SAX方式解析,特點(diǎn)是事件驅(qū)動(dòng)福侈,下面情況都會(huì)通知代理
  • 當(dāng)掃描到文檔(Document)的開始與結(jié)束
  • 當(dāng)掃描到元素(Element)的開始與結(jié)束

NSXMLParserDelegate

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

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

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

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

代碼如下:

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

@implementation ViewController

// 進(jìn)行懶加載
-(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)用這個(gè)方法,代表開始解析)
        [parser parse];
       
        //5.刷新TableView(全部解析完卢未,才會(huì)刷新)
        [self.tableView reloadData];

#pragma mark  NSXMLParserDelegate  start

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

/*
 2.解析XML文檔中的每一個(gè)元素,會(huì)調(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文檔中的每一個(gè)元素結(jié)束
 */
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
//     NSLog(@"didEndElement");
}

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

五肪凛、GDataXML

1、GDataXML配置

GDataXML基于libxml2庫(kù)辽社,得做以下配置
1伟墙、導(dǎo)入libxml2庫(kù)


1.png

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

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

Snip20151009_312.png

3滴铅、設(shè)置鏈接參數(shù)(自動(dòng)鏈接libxml2庫(kù))

在Other Linker Flags中加入-lxml2

Snip20151009_313.png

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

2.png

2汉匙、GDataXML使用

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

 //2.創(chuàng)建請(qǐng)求對(duì)象   
 NSURLRequest *request = [NSURLRequest requestWithURL:url];   
   
 //3.發(fā)送異步請(qǐng)求   
 [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {             
         //4.解析數(shù)據(jù)       
         //4.1 加載整個(gè)XML文檔        
         GDataXMLDocument *doc  = [[GDataXMLDocument alloc]initWithData:data options:kNilOptions error:nil];               
         //4.2 拿到根元素      
          NSArray *eles =  [doc.rootElement elementsForName:@"video"];        
         //4.3 取出每個(gè)子元素的屬性并轉(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來(lái)表示噩翠,也可以用XML來(lái)表示


4.png

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末伤锚,一起剝皮案震驚了整個(gè)濱河市擅笔,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌屯援,老刑警劉巖猛们,帶你破解...
    沈念sama閱讀 211,561評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異狞洋,居然都是意外死亡弯淘,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門徘铝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)耳胎,“玉大人,你說(shuō)我怎么就攤上這事惕它∨挛纾” “怎么了?”我有些...
    開封第一講書人閱讀 157,162評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵淹魄,是天一觀的道長(zhǎng)郁惜。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么兆蕉? 我笑而不...
    開封第一講書人閱讀 56,470評(píng)論 1 283
  • 正文 為了忘掉前任羽戒,我火速辦了婚禮,結(jié)果婚禮上虎韵,老公的妹妹穿的比我還像新娘易稠。我一直安慰自己,他們只是感情好包蓝,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,550評(píng)論 6 385
  • 文/花漫 我一把揭開白布驶社。 她就那樣靜靜地躺著,像睡著了一般测萎。 火紅的嫁衣襯著肌膚如雪亡电。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,806評(píng)論 1 290
  • 那天硅瞧,我揣著相機(jī)與錄音份乒,去河邊找鬼。 笑死腕唧,一個(gè)胖子當(dāng)著我的面吹牛或辖,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播四苇,決...
    沈念sama閱讀 38,951評(píng)論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼孝凌,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了月腋?” 一聲冷哼從身側(cè)響起蟀架,我...
    開封第一講書人閱讀 37,712評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎榆骚,沒想到半個(gè)月后片拍,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,166評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡妓肢,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,510評(píng)論 2 327
  • 正文 我和宋清朗相戀三年捌省,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片碉钠。...
    茶點(diǎn)故事閱讀 38,643評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡纲缓,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出喊废,到底是詐尸還是另有隱情祝高,我是刑警寧澤,帶...
    沈念sama閱讀 34,306評(píng)論 4 330
  • 正文 年R本政府宣布污筷,位于F島的核電站工闺,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜陆蟆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,930評(píng)論 3 313
  • 文/蒙蒙 一雷厂、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧叠殷,春花似錦改鲫、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至诊县,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間措左,已是汗流浹背依痊。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留怎披,地道東北人胸嘁。 一個(gè)月前我還...
    沈念sama閱讀 46,351評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像凉逛,于是被迫代替她去往敵國(guó)和親性宏。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,509評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

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