XML(extensible Markup Language) ,是一種數據標記語言 & 傳輸格式html
與html的區別:html用於顯示信息;xml用於存儲&傳輸信息node
標籤可進行自定義數組
XML容許做者定義本身的標籤和文檔結構
自我描述性app
> **XML文檔實例** > > ``` > <?xml version="1.0" encoding="ISO-8859-1"?> > <!-- XML版本(1.0)和所使用編碼方法--> > <note> > <!-- 根元素 --> > <to>George</to> > <from>John</from> > <heading>Reminder</heading> > <body>Dont't forget the meeting!</body> > <!-- 根元素下的4個子元素--> > </note> > <!-- 根元素的結尾 --> > ``` > > 僅僅是一個純文本,有文本處理能力的軟件均可以處理xml
可拓展性dom
在不中斷解析、應用程序的狀況下進行拓展。
可跨平臺數據傳輸ide
可在不兼容的系統之間進行交換數據,下降了複雜性
數據共享方便性能
XML以純文本進行存儲,獨立於軟件、硬件和應用程序的數據存儲方式,使得不一樣應用程序、軟件和硬件都能訪問xml的數據
元素要關閉標籤ui
`< p >this is a bitch <p>`
對大小寫敏感this
< P >這是錯誤的<p> < p >這是正確的 <p>
必需要有根元素(父元素)編碼
<root> <kid> </kid> </root>
屬性值必須加引號
<note date="16/08/08"> </note>
實體引用 | 符號 | 含義 |
---|---|---|
<; | < | 小於 |
> ; | > | 大於 |
&; | & | 和浩 |
&apos; | ‘ | 單引號 |
"; | " | 雙引號 |
元素不能使用&(實體的開始)和<(新元素的開始)
註釋
`<!-- This is a comment -->`
XML的元素、屬性和屬性值
> 文檔實例 > > ``` > <bookstore> > <book category="CHILDREN"> > <title lang="en"> Harry Potter </title> > <author> JK.Rowling</author> > </book> > <book category="WEB"> > <title lang="en"> woshiPM </title> > <author>Carson_Ho</author> > </book> > </bookstore> > ``` > > 其中,<bookstore>是根元素;<book>是子元素,也是元素類型之一;而<book>中含有屬性,即category,屬性值是CHILDREN;而元素<author>則擁有文本內容( JK.Rowling)
元素與屬性的差異
屬性即提供元素額外的信息,但不屬於數據組成部分的信息。 > 範例一 > > ``` > <bookstore> > <book category="CHILDREN"> > <title lang="en"> Harry Potter </title> > <author> JK.Rowling</author> > </book> > ``` > > 範例二 > > ``` > <bookstore> > <book > > <category>CHILDREN<category> > <title lang="en"> Harry Potter </title> > <author> JK.Rowling</author> > </book> > ``` > > 範例一和二提供的信息是徹底相同的。
通常狀況下,請使用元素,由於
使用屬性的狀況:用於分配ID索引,用於標識XML元素。
實例
<bookstore> <book id = "501"> <category>CHILDREN<category> <title lang="en"> Harry Potter </title> <author> JK.Rowling</author> </book> <book id = "502"> <category>CHILDREN<category> <title lang="en"> Harry Potter </title> <author> JK.Rowling</author> </book> <bookstore>上述屬性(id)僅用於標識不一樣的便籤,並非數據的組成部分
XML元素命名規則
<![CDATA["傳輸的文本 "]]>
XML文檔中的元素會造成一種樹結構,從根部開始,而後拓展到每一個樹葉(節點),下面將以實例說明XML的樹結構。
假設一個XML文件以下
<?xml version ="1.0" encoding="UTF-8"?> <簡歷> <基本資料> <求職意向> <自我評價> <其餘信息> <聯繫方式> <個人做品> </簡歷>
XML節點解釋
XML文件是由節點構成的。它的第一個節點爲「根節點」。一個XML文件必須有且只能有一個根節點,其餘節點都必須是它的子節點。
this 表明整個XML文件,它的根節點就是 this.firstChild 。 this.firstChild.childNodes 則返回由根節點的全部子節點組成的節點數組。
每一個子節點又能夠有本身的子節點。節點編號由0開始,根節點的第一個子節點爲 this.firstChild.childNodes[0],它的子節點數組就是this.firstChild.childNodes[0].childNodes 。
根節點第一個子節點的第二個子節點 this.firstChild.childNodes[0].childNodes[1],它返回的是一個XML對象(Object) 。這裏須要特別注意,節點標籤之間的數據自己也視爲一個節點 this.firstChild.childNodes[0].childNodes[1].firstChild ,而不是一個值。
咱們解析XML的最終目的固然就是得到數據的值:
this.firstChild.childNodes[0].childNodes[1].firstChild.nodeValue 。
請注意區分:節點名稱(<性別></性別>)和之間的文本內容(男)能夠看成是節點,也能夠看成是一個值
節點:
名稱:this.firstChild.childNodes[0].childNodes[1]
文本內容:this.firstChild.childNodes[0].childNodes[1].firstChild值:
名稱:this.firstChild.childNodes[0].childNodes[1].nodeValue
(節點名稱有時也是咱們須要的數據)
文本內容:this.firstChild.childNodes[0].childNodes[1].nodeName
在瞭解完XML以後,是時候來學下如何進行XML的解析了
解析XML,即從XML中提取有用的信息
基於文檔驅動方式
假設須要解析的XML文檔以下(subject.xml)
<?xml version ="1.0" encoding="UTF-8"?>` <code> <language id="1"> <name>Java</name> <usage>Android</usage> </language> <language id="2"> <name>Swift#</name> <usage>iOS</usage> </language> <language id="3"> <name>Html5</name> <usage>Web</usage> </language> </code>
核心代碼
public static List<subject> getSubjectList(InputStream stream) { tv = (TextView)findViewById(R.id.tv); try { //打開xml文件到輸入流 InputStream stream = getAssets().open("subject.xml"); //獲得 DocumentBuilderFactory 對象 DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); //獲得DocumentBuilder對象 DocumentBuilder builder = builderFactory.newDocumentBuilder(); //創建Document存放整個xml的Document對象數據 Document document = builder.parse(stream); //獲得 XML數據的"根節點" Element element = document.getDocumentElement(); //獲取根節點的全部language的節點 NodeList list = element.getElementsByTagName("language"); //遍歷全部節點 for (int i= 0;i<=list.getLength();i++){ //獲取lan的全部子元素 Element language = (Element) list.item(i); //獲取language的屬性(這裏即爲id)並顯示 tv.append(lan.getAttribute("id")+"\n"); //獲取language的子元素 name 並顯示 tv.append(sub.getElementsByTagName("name").item(0).getTextContent()+"\n"); //獲取language的子元素usage 並顯示 tv.append(sub.getElementsByTagName("usage").item(0).getTextContent()+"\n"); }
總結Dom解析的步驟
一、調用 DocumentBuilderFactory.newInstance() 方法獲得 DOM 解析器工廠類實例。
二、調用解析器工廠實例類的 newDocumentBuilder() 方法獲得 DOM 解析器對象
三、調用 DOM 解析器對象的 parse() 方法解析 XML 文檔獲得表明整個文檔的 Document 對象。
基於事件驅動
核心代碼
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 { // 判斷是否到了文件的結尾 while (xrp.getEventType() != XmlPullParser.END_DOCUMENT) { //文件的內容的起始標籤開始,這裏的起始標籤是subject.xml文件裏面<subjects>標籤下面的第一個標籤 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 + "種語言"+"\n"); //能夠調用XmlPullParser的getAttributte()方法來獲取屬性的值 sb.append("語言id是:"+xrp.getAttributeValue(0)+"\n"); } else if(tagname.equals("name")){ //能夠調用XmlPullParser的nextText()方法來獲取節點的值 sb.append("語言名稱是:"+xrp.nextText()+"\n"); } else if(tagname.equals("teacher")){ sb.append("用途是:"+xrp.nextText()+"\n"); } break; case XmlPullParser.END_TAG: break; case XmlPullParser.TEXT: break; } //解析下一個事件 xrp.next(); } //StringBuilder要調用toString()方法並顯示 et.setText(sb.toString()); } catch (XmlPullParserException e) { } catch (IOException e) { e.printStackTrace(); } } }); }
SAX解析
一樣是採用事件驅動進行解析,但相比pull解析方法,採用SAX方式進行XML解析可能會較爲複雜,這裏就不做實例展現,有興趣的童鞋們能夠本身去嘗試下,畢竟實踐出真知!
DOM方式
原理:基於文檔驅動,是先把dom所有文件讀入到內存中,構建一個主流內存的樹結構,而後使用DOM的API遍歷全部數據,調用API檢索想要的數據和操做數據。
因此,DOM方式的優缺點是:
特色:
**優勢**:整個文檔樹存在內存中,可對XML文檔進行操做:刪除、修改等等;可屢次訪問已解析的文檔;因爲在內存中以樹形結構存放,所以檢索和更新效率會更高。; **缺點**:解析 XML 文件時會將整個 XML 文件的內容解析成樹型結構存放在內存中並建立新對象,比較消耗時間和內存;
使用情境
對於像手機這樣的移動設備來說,內存是很是有限的,在XML文檔比較小、須要對解析文檔進行必定的操做且一旦解析了文檔須要屢次訪問這些數據的狀況下能夠考慮使用DOM方式,由於其檢索和解析效率較高
SAX方式
特色:
**優勢**:解析效率高、佔存少、靈活性高 **缺點**:解析方法複雜(API接口複雜),代碼量大;可拓展性差:沒法對 XML 樹內容結構進行任何修改
使用情境
適用於須要處理大型 XML 文檔、性能要求較高、不須要對解析文檔進行修改且不須要對解析文檔屢次訪問的場合
PULL方式
原理:PULL的解析方式與SAX解析相似,都是基於事件的模式。
PULL提供了開始元素和結束元素。當某個元素開始時,咱們能夠調用parser.nextText從XML文檔中提取全部字符數據,與SAX不一樣的是,在PULL解析過程當中觸發相應的事件調用方法返回的是數字,且咱們須要本身獲取產生的事件而後作相應的操做,而不像SAX那樣由處理器觸發一種事件的方法從而執行代碼。當解釋到一個文檔結束時,自動生成EndDocument事件。
特色:
**優勢**:SAX的優勢PULL都有,並且解析方法比SAX更加簡單 **缺點**:可拓展性差:沒法對 XML 樹內容結構進行任何修改
使用情境
適用於須要處理大型 XML 文檔、性能要求較高、不須要對解析文檔進行修改且不須要對解析文檔屢次訪問的場合
一樣的使用情景,在SAX和PULL解析方法中,更加推薦PULL方法
本文對現今主流的數據傳輸格式XML進行了簡單的介紹,但願你們實踐出真知哦!