摘要:我們解析的最終目的當(dāng)然就是獲得數(shù)據(jù)的值。所以,方式的優(yōu)缺點(diǎn)是特點(diǎn)優(yōu)點(diǎn)整個(gè)文檔樹(shù)存在內(nèi)存中,可對(duì)文檔進(jìn)行操作刪除修改等等可多次訪問(wèn)已解析的文檔由于在內(nèi)存中以樹(shù)形結(jié)構(gòu)存放,因此檢索和更新效率會(huì)更高。
目錄 定義
XML(extensible Markup Language) ,是一種數(shù)據(jù)標(biāo)記語(yǔ)言 & 傳輸格式
作用對(duì)數(shù)據(jù)進(jìn)行標(biāo)記(結(jié)構(gòu)化數(shù)據(jù))
對(duì)數(shù)據(jù)進(jìn)行存儲(chǔ)
對(duì)數(shù)據(jù)進(jìn)行傳輸
XML特點(diǎn)與html的區(qū)別:html用于顯示信息;xml用于存儲(chǔ)&傳輸信息
標(biāo)簽可進(jìn)行自定義
XML允許作者定義自己的標(biāo)簽和文檔結(jié)構(gòu)
自我描述性
> **XML文檔實(shí)例** > > ``` > > >> > > > ``` > > 僅僅是一個(gè)純文本,有文本處理能力的軟件都可以處理xmlGeorge >John >Reminder > Dont"t forget the meeting! > >
可拓展性
在不中斷解析、應(yīng)用程序的情況下進(jìn)行拓展。
可跨平臺(tái)數(shù)據(jù)傳輸
可在不兼容的系統(tǒng)之間進(jìn)行交換數(shù)據(jù),降低了復(fù)雜性
數(shù)據(jù)共享方便
XML以純文本進(jìn)行存儲(chǔ),獨(dú)立于軟件、硬件和應(yīng)用程序的數(shù)據(jù)存儲(chǔ)方式,使得不同應(yīng)用程序、軟件和硬件都能訪問(wèn)xml的數(shù)據(jù)語(yǔ)法
元素要關(guān)閉標(biāo)簽
`< p >this is a bitch`
對(duì)大小寫敏感
< P >這是錯(cuò)誤的< p >這是正確的
必須要有根元素(父元素)
屬性值必須加引號(hào)
實(shí)體引用
實(shí)體引用 | 符號(hào) | 含義 |
---|---|---|
<; | < | 小于 |
> ; | > | 大于 |
&; | & | 和浩 |
&apos; | ‘ | 單引號(hào) |
"; | " | 雙引號(hào) |
元素不能使用&(實(shí)體的開(kāi)始)和<(新元素的開(kāi)始)
注釋
``
XML的元素、屬性和屬性值
> 文檔實(shí)例 > > ``` >> > ``` > > 其中,> >Harry Potter >JK.Rowling >> >woshiPM >Carson_Ho >是根元素; 是子元素,也是元素類型之一;而 中含有屬性,即category,屬性值是CHILDREN;而元素 則擁有文本內(nèi)容( JK.Rowling)
元素與屬性的差別
屬性即提供元素額外的信息,但不屬于數(shù)據(jù)組成部分的信息。 > 范例一 > > ``` >> > > ``` > > 范例二 > > ``` >Harry Potter >JK.Rowling >> > > ``` > > 范例一和二提供的信息是完全相同的。CHILDREN > Harry Potter >JK.Rowling >
一般情況下,請(qǐng)使用元素,因?yàn)?/p>
屬性無(wú)法描述樹(shù)結(jié)構(gòu)(元素可以)
屬性不容易拓展(元素可以)
使用屬性的情況:用于分配ID索引,用于標(biāo)識(shí)XML元素。
實(shí)例
CHILDREN Harry Potter JK.Rowling CHILDREN Harry Potter JK.Rowling 上述屬性(id)僅用于標(biāo)識(shí)不同的便簽,并不是數(shù)據(jù)的組成部分
XML元素命名規(guī)則
不能以數(shù)字或標(biāo)點(diǎn)符號(hào)開(kāi)頭
不能包含空格
不能以xml開(kāi)頭
CDATA
不被解析器解析的文本數(shù)據(jù),所有xml文檔都會(huì)被解析器解析(cdata區(qū)段除外)
PCDATA
被解析的字符數(shù)據(jù)
XML文檔中的元素會(huì)形成一種樹(shù)結(jié)構(gòu),從根部開(kāi)始,然后拓展到每個(gè)樹(shù)葉(節(jié)點(diǎn)),下面將以實(shí)例說(shuō)明XML的樹(shù)結(jié)構(gòu)。
假設(shè)一個(gè)XML文件如下
<?xml version ="1.0" encoding="UTF-8"?> <簡(jiǎn)歷> <基本資料> <求職意向> <自我評(píng)價(jià)> <其他信息> <聯(lián)系方式> <我的作品> 簡(jiǎn)歷>
其樹(shù)結(jié)構(gòu)如下
XML節(jié)點(diǎn)解釋
XML文件是由節(jié)點(diǎn)構(gòu)成的。它的第一個(gè)節(jié)點(diǎn)為“根節(jié)點(diǎn)”。一個(gè)XML文件必須有且只能有一個(gè)根節(jié)點(diǎn),其他節(jié)點(diǎn)都必須是它的子節(jié)點(diǎn)。
this 代表整個(gè)XML文件,它的根節(jié)點(diǎn)就是 this.firstChild 。 this.firstChild.childNodes 則返回由根節(jié)點(diǎn)的所有子節(jié)點(diǎn)組成的節(jié)點(diǎn)數(shù)組。
每個(gè)子節(jié)點(diǎn)又可以有自己的子節(jié)點(diǎn)。節(jié)點(diǎn)編號(hào)由0開(kāi)始,根節(jié)點(diǎn)的第一個(gè)子節(jié)點(diǎn)為 this.firstChild.childNodes[0],它的子節(jié)點(diǎn)數(shù)組就是this.firstChild.childNodes[0].childNodes 。
根節(jié)點(diǎn)第一個(gè)子節(jié)點(diǎn)的第二個(gè)子節(jié)點(diǎn) this.firstChild.childNodes[0].childNodes[1],它返回的是一個(gè)XML對(duì)象(Object) 。這里需要特別注意,節(jié)點(diǎn)標(biāo)簽之間的數(shù)據(jù)本身也視為一個(gè)節(jié)點(diǎn) this.firstChild.childNodes[0].childNodes[1].firstChild ,而不是一個(gè)值。
我們解析XML的最終目的當(dāng)然就是獲得數(shù)據(jù)的值:
this.firstChild.childNodes[0].childNodes[1].firstChild.nodeValue 。
請(qǐng)注意區(qū)分:節(jié)點(diǎn)名稱(<性別>性別>)和之間的文本內(nèi)容(男)可以當(dāng)作是節(jié)點(diǎn),也可以當(dāng)作是一個(gè)值
節(jié)點(diǎn):
名稱:this.firstChild.childNodes[0].childNodes[1]
文本內(nèi)容:this.firstChild.childNodes[0].childNodes[1].firstChild值:
名稱:this.firstChild.childNodes[0].childNodes[1].nodeValue
(節(jié)點(diǎn)名稱有時(shí)也是我們需要的數(shù)據(jù))
文本內(nèi)容:this.firstChild.childNodes[0].childNodes[1].nodeName
在了解完XML之后,是時(shí)候來(lái)學(xué)下如何進(jìn)行XML的解析了
XML解析解析XML,即從XML中提取有用的信息
基于文檔驅(qū)動(dòng)方式
主流方式:DOM方式
簡(jiǎn)介:XML DOM(XML Document Object Model),XML文件對(duì)象模型,定義了訪問(wèn)和操作xml文檔元素的方法和接口
工作原理: DOM是基于樹(shù)形結(jié)構(gòu)的的節(jié)點(diǎn)的文檔驅(qū)動(dòng)方法。使用DOM對(duì)XML文件進(jìn)行操作時(shí),首先解析器讀入整個(gè)XML文檔到內(nèi)存中,然后解析全部文件,并將文件分為獨(dú)立的元素、屬性等,以樹(shù)結(jié)構(gòu)的形式在內(nèi)存中對(duì)XML文件進(jìn)行表示,開(kāi)發(fā)人員通過(guò)使用DOM API遍歷XML樹(shù),根據(jù)需要修改文檔或檢索所需數(shù)據(jù)
假設(shè)需要解析的XML文檔如下(subject.xml)
<?xml version ="1.0" encoding="UTF-8"?>`
Java
Android
Swift#
iOS
Html5
Web
核心代碼
public static ListgetSubjectList(InputStream stream) { tv = (TextView)findViewById(R.id.tv); try { //打開(kāi)xml文件到輸入流 InputStream stream = getAssets().open("subject.xml"); //得到 DocumentBuilderFactory 對(duì)象 DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); //得到DocumentBuilder對(duì)象 DocumentBuilder builder = builderFactory.newDocumentBuilder(); //建立Document存放整個(gè)xml的Document對(duì)象數(shù)據(jù) Document document = builder.parse(stream); //得到 XML數(shù)據(jù)的"根節(jié)點(diǎn)" Element element = document.getDocumentElement(); //獲取根節(jié)點(diǎn)的所有l(wèi)anguage的節(jié)點(diǎn) NodeList list = element.getElementsByTagName("language"); //遍歷所有節(jié)點(diǎn) for (int i= 0;i<=list.getLength();i++){ //獲取lan的所有子元素 Element language = (Element) list.item(i); //獲取language的屬性(這里即為id)并顯示 tv.append(lan.getAttribute("id")+" "); //獲取language的子元素 name 并顯示 tv.append(sub.getElementsByTagName("name").item(0).getTextContent()+" "); //獲取language的子元素usage 并顯示 tv.append(sub.getElementsByTagName("usage").item(0).getTextContent()+" "); }
總結(jié)Dom解析的步驟
1、調(diào)用 DocumentBuilderFactory.newInstance() 方法得到 DOM 解析器工廠類實(shí)例。
2、調(diào)用解析器工廠實(shí)例類的 newDocumentBuilder() 方法得到 DOM 解析器對(duì)象
3、調(diào)用 DOM 解析器對(duì)象的 parse() 方法解析 XML 文檔得到代表整個(gè)文檔的 Document 對(duì)象。
基于事件驅(qū)動(dòng)
主流方式:SAX、PULL方式
解析方式:可直接根據(jù)需要讀取所需的JSON數(shù)據(jù),不需要像DOM方法把文檔先入到內(nèi)存中
工作原理:PULL的解析方式與SAX解析類似,都是基于事件的模式。
PULL提供了開(kāi)始元素和結(jié)束元素。當(dāng)某個(gè)元素開(kāi)始時(shí),我們可以調(diào)用parser.nextText從XML文檔中提取所有字符數(shù)據(jù),與SAX不同的是,在PULL解析過(guò)程中觸發(fā)相應(yīng)的事件調(diào)用方法返回的是數(shù)字,且我們需要自己獲取產(chǎn)生的事件然后做相應(yīng)的操作,而不像SAX那樣由處理器觸發(fā)一種事件的方法從而執(zhí)行代碼。當(dāng)解釋到一個(gè)文檔結(jié)束時(shí),自動(dòng)生成EndDocument事件。
核心代碼
public class MainActivity extends Activity { private EditText et; private Button myButton; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); myButton = (Button) this.findViewById(R.id.btn01); et = (EditText) this.findViewById(R.id.edittext01); myButton.setOnClickListener(new OnClickListener() { //可變字符序列,比StringBuffer塊 StringBuilder sb = new StringBuilder(""); Resources res = getResources(); XmlResourceParser xrp = res.getXml(R.xml.subject); @Override public void onClick(View v) { int counter = 0; try { // 判斷是否到了文件的結(jié)尾 while (xrp.getEventType() != XmlPullParser.END_DOCUMENT) { //文件的內(nèi)容的起始標(biāo)簽開(kāi)始,這里的起始標(biāo)簽是subject.xml文件里面標(biāo)簽下面的第一個(gè)標(biāo)簽 int eventType=xrp.getEventType(); switch (eventType) { case XmlPullParser.START_DOCUMENT: break; case XmlPullParser.START_TAG: String tagname = xrp.getName(); if (tagname.endsWith("language")) { counter++; sb.append("這是第" + counter + "種語(yǔ)言"+" "); //可以調(diào)用XmlPullParser的getAttributte()方法來(lái)獲取屬性的值 sb.append("語(yǔ)言id是:"+xrp.getAttributeValue(0)+" "); } else if(tagname.equals("name")){ //可以調(diào)用XmlPullParser的nextText()方法來(lái)獲取節(jié)點(diǎn)的值 sb.append("語(yǔ)言名稱是:"+xrp.nextText()+" "); } else if(tagname.equals("teacher")){ sb.append("用途是:"+xrp.nextText()+" "); } break; case XmlPullParser.END_TAG: break; case XmlPullParser.TEXT: break; } //解析下一個(gè)事件 xrp.next(); } //StringBuilder要調(diào)用toString()方法并顯示 et.setText(sb.toString()); } catch (XmlPullParserException e) { } catch (IOException e) { e.printStackTrace(); } } }); }
SAX解析
工作原理:基于事件驅(qū)動(dòng),在讀取XML文檔內(nèi)容時(shí),事件源順序地對(duì)文檔進(jìn)行掃描,當(dāng)掃描到文檔的開(kāi)始與結(jié)束(Document)標(biāo)簽、節(jié)點(diǎn)元素的開(kāi)始與結(jié)束(Element)標(biāo)簽時(shí),直接調(diào)用對(duì)應(yīng)的方法,并將狀態(tài)信息以參數(shù)的形式傳遞到方法中,然后我們可以依據(jù)狀態(tài)信息來(lái)執(zhí)行相關(guān)的自定義操作。
同樣是采用事件驅(qū)動(dòng)進(jìn)行解析,但相比pull解析方法,采用SAX方式進(jìn)行XML解析可能會(huì)較為復(fù)雜,這里就不作實(shí)例展示,有興趣的童鞋們可以自己去嘗試下,畢竟實(shí)踐出真知!
DOM、SAX、PULL三類方式對(duì)比DOM方式
原理:基于文檔驅(qū)動(dòng),是先把dom全部文件讀入到內(nèi)存中,構(gòu)建一個(gè)主流內(nèi)存的樹(shù)結(jié)構(gòu),然后使用DOM的API遍歷所有數(shù)據(jù),調(diào)用API檢索想要的數(shù)據(jù)和操作數(shù)據(jù)。
所以,DOM方式的優(yōu)缺點(diǎn)是:
特點(diǎn):
**優(yōu)點(diǎn)**:整個(gè)文檔樹(shù)存在內(nèi)存中,可對(duì)XML文檔進(jìn)行操作:刪除、修改等等;可多次訪問(wèn)已解析的文檔;由于在內(nèi)存中以樹(shù)形結(jié)構(gòu)存放,因此檢索和更新效率會(huì)更高。; **缺點(diǎn)**:解析 XML 文件時(shí)會(huì)將整個(gè) XML 文件的內(nèi)容解析成樹(shù)型結(jié)構(gòu)存放在內(nèi)存中并創(chuàng)建新對(duì)象,比較消耗時(shí)間和內(nèi)存;
使用情境
對(duì)于像手機(jī)這樣的移動(dòng)設(shè)備來(lái)講,內(nèi)存是非常有限的,在XML文檔比較小、需要對(duì)解析文檔進(jìn)行一定的操作且一旦解析了文檔需要多次訪問(wèn)這些數(shù)據(jù)的情況下可以考慮使用DOM方式,因?yàn)槠錂z索和解析效率較高
SAX方式
原理:基于事件驅(qū)動(dòng),在讀取XML文檔內(nèi)容時(shí),事件源順序地對(duì)文檔進(jìn)行掃描,當(dāng)掃描到文檔的開(kāi)始與結(jié)束(Document)標(biāo)簽、節(jié)點(diǎn)元素的開(kāi)始與結(jié)束(Element)標(biāo)簽時(shí),直接調(diào)用對(duì)應(yīng)的方法,并將狀態(tài)信息以參數(shù)的形式傳遞到方法中,然后我們可以依據(jù)狀態(tài)信息來(lái)執(zhí)行相關(guān)的自定義操作。
特點(diǎn):
**優(yōu)點(diǎn)**:解析效率高、占存少、靈活性高 **缺點(diǎn)**:解析方法復(fù)雜(API接口復(fù)雜),代碼量大;可拓展性差:無(wú)法對(duì) XML 樹(shù)內(nèi)容結(jié)構(gòu)進(jìn)行任何修改
使用情境
適用于需要處理大型 XML 文檔、性能要求較高、不需要對(duì)解析文檔進(jìn)行修改且不需要對(duì)解析文檔多次訪問(wèn)的場(chǎng)合
PULL方式
原理:PULL的解析方式與SAX解析類似,都是基于事件的模式。
PULL提供了開(kāi)始元素和結(jié)束元素。當(dāng)某個(gè)元素開(kāi)始時(shí),我們可以調(diào)用parser.nextText從XML文檔中提取所有字符數(shù)據(jù),與SAX不同的是,在PULL解析過(guò)程中觸發(fā)相應(yīng)的事件調(diào)用方法返回的是數(shù)字,且我們需要自己獲取產(chǎn)生的事件然后做相應(yīng)的操作,而不像SAX那樣由處理器觸發(fā)一種事件的方法從而執(zhí)行代碼。當(dāng)解釋到一個(gè)文檔結(jié)束時(shí),自動(dòng)生成EndDocument事件。
特點(diǎn):
**優(yōu)點(diǎn)**:SAX的優(yōu)點(diǎn)PULL都有,而且解析方法比SAX更加簡(jiǎn)單 **缺點(diǎn)**:可拓展性差:無(wú)法對(duì) XML 樹(shù)內(nèi)容結(jié)構(gòu)進(jìn)行任何修改
使用情境
適用于需要處理大型 XML 文檔、性能要求較高、不需要對(duì)解析文檔進(jìn)行修改且不需要對(duì)解析文檔多次訪問(wèn)的場(chǎng)合
同樣的使用情景,在SAX和PULL解析方法中,更加推薦PULL方法
總結(jié)本文對(duì)現(xiàn)今主流的數(shù)據(jù)傳輸格式XML進(jìn)行了簡(jiǎn)單的介紹,希望大家實(shí)踐出真知哦!
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/70533.html
什么是XML? XML:extensiable markup language 被稱作可擴(kuò)展標(biāo)記語(yǔ)言 XML簡(jiǎn)單的歷史介紹: gml->sgml->html->xml gml(通用標(biāo)記語(yǔ)言)–在不同的機(jī)器進(jìn)行通信的數(shù)據(jù)規(guī)范 sgml(標(biāo)準(zhǔn)通用標(biāo)記語(yǔ)言) html(超文本標(biāo)記語(yǔ)言) 為什么我們需要使用XML呢? ①我們沒(méi)有XML這種語(yǔ)言之前,我們使用的是String作為兩個(gè)程序之間的通訊!現(xiàn)在問(wèn)...
什么是XML? XML:extensiable markup language 被稱作可擴(kuò)展標(biāo)記語(yǔ)言 XML簡(jiǎn)單的歷史介紹: gml->sgml->html->xml gml(通用標(biāo)記語(yǔ)言)–在不同的機(jī)器進(jìn)行通信的數(shù)據(jù)規(guī)范 sgml(標(biāo)準(zhǔn)通用標(biāo)記語(yǔ)言) html(超文本標(biāo)記語(yǔ)言) 為什么我們需要使用XML呢? ①我們沒(méi)有XML這種語(yǔ)言之前,我們使用的是String作為兩個(gè)程序之間的通訊!現(xiàn)在問(wèn)...
摘要:解析和我們?cè)跍y(cè)試一個(gè)的撒的撒范德薩發(fā)大水發(fā)解析和我們?cè)跍y(cè)試一個(gè)的撒的撒范德薩發(fā)大水發(fā)解析和我們?cè)跍y(cè)試一個(gè)的撒的撒范德薩發(fā)大水發(fā)解析和我們?cè)跍y(cè)試一個(gè)的撒的撒范德薩發(fā)大水發(fā)解析和我們?cè)跍y(cè)試一個(gè)的撒的撒范德薩發(fā)大水發(fā)解析和我們?cè)跍y(cè)試一個(gè)的撒的撒范 XML 解析 Xml Pull Parser 和 SAX 我們?cè)跍y(cè)試一個(gè)的撒的撒范德薩發(fā)大水發(fā)XML 解析 Xml Pull Parser 和 S...
摘要:解析獲取解析器獲取文檔獲取根節(jié)點(diǎn)獲取根節(jié)點(diǎn)下所有的子節(jié)點(diǎn),也可以根據(jù)標(biāo)簽名稱獲取指定的直接點(diǎn)獲取元素的名稱和里面的文本創(chuàng)建創(chuàng)建節(jié)點(diǎn)創(chuàng)建屬性設(shè)置文本設(shè)置關(guān)系關(guān)于解析先講到這里了,請(qǐng)繼續(xù)關(guān)注樂(lè)字節(jié),后續(xù)超級(jí)干貨奉上,快快樂(lè)樂(lè)學(xué)。 大家好,樂(lè)字節(jié)的小樂(lè)又來(lái)了,Java技術(shù)分享哪里少的了小樂(lè)!上次我們說(shuō)了可擴(kuò)展標(biāo)記語(yǔ)言XML之二:XML語(yǔ)言格式規(guī)范、文檔組成,本文將介紹重點(diǎn)——XML解析。sh...
摘要:而正好相反,采用一種拉的方式,由應(yīng)用程序主動(dòng)從解析器中獲取當(dāng)前事件然后更具需求處理保存或者忽略。通過(guò)將解析器事件變成一級(jí)對(duì)象,從而讓應(yīng)用程序可以采用面向?qū)ο蟮姆绞教幚硭鼈儭? 簡(jiǎn)介 StAX,全稱Streaming API for XML,一種全新的,基于流的JAVA XML解析標(biāo)準(zhǔn)類庫(kù)。其最終版本于 2004 年 3 月發(fā)布,并成為了 JAXP 1.4(將包含在即將發(fā)布的 Java 6...
閱讀 948·2021-11-22 12:09
閱讀 3715·2021-09-27 13:36
閱讀 1404·2021-08-20 09:37
閱讀 4027·2019-12-27 12:22
閱讀 2365·2019-08-30 15:55
閱讀 2370·2019-08-30 13:16
閱讀 2832·2019-08-26 17:06
閱讀 3442·2019-08-23 18:32