轉載請注明原文地址:http://www.cnblogs.com/ygj0930/p/6646572.html
XML文檔以層級標簽的形式來組織數據,多用於配置文件、存儲靜態數據、交換數據。
XML語法
1 每個XML文檔都由XML序言開始,在前面的代碼中的第一行便是XML序言,<?xml version="1.0"?>
2 任何的起始標簽都必須有一個結束標簽。
3 標簽必須按合適的順序進行嵌套,所以結束標簽必須按鏡像順序匹配起始標簽。
4 標簽如果有屬性,屬性值必須加雙引號。
XML文檔解析
首先我們要知道,“XML中的內容都是結點”,這句話的意思是:XML文檔中,無論是 <> </> 符號的里面的內容(屬性)、之間的內容(結點值)、還是 <> 本身(結點),都是Node,就連標簽之間的換行、空格都是一個節點。明白這個很重要,因為下面遍歷結點時,返回的 屬性名值對 、結點值內容、結點本身 都是一個Node類型。
一:DOM方法
Java自身原生的兩種解析XML方式之一——DOM方法,原理是:首先在內存中創建一個Document對象,然后把XML文檔讀取進來賦值給這個dom對象。由於dom對象是基於樹結構的,所以對dom對象進行遍歷即可。對內存中的dom對象可以進行查詢、修改、刪除操作,還可以寫回原XML文檔保存修改。
優點:
a、由於整棵樹在內存中,因此可以對xml文檔隨機訪問
b、可以對xml文檔進行修改操作
缺點:
a、整個文檔必須一次性解析完
a、由於整個文檔都需要載入內存,對於大文檔成本高
操作步驟:
1:創建DocumentBuilderFactory,由newInstance()方法獲取工廠實例;
2:由工廠創建DocumentBuilder;
3:通過 Document dom=builder.parse(file); 讀取xml文檔創建dom對象;
4:通過dom對象的一系列方法獲取某個結點、某名字的結點列表:
Element getElementById(String elementId)
返回具有帶給定值的 ID 屬性的 Element。
NodeList getElementsByTagName(String tagname)
按文檔順序返回包含在文檔中且具有給定標記名稱的所有 Element 的 NodeList。
5:通過NodeList對象獲取結點列表中某個結點:
Node item(int index)
返回集合中的第 index 個項。
6:通過Node對象讀取結點屬性:
NamedNodeMap getAttributes()
包含此節點的屬性的 NamedNodeMap(如果它是 Element);否則為 null。
然后對NamedNodeMap對象調用以下方法獲取屬性:(前面我們說過,屬性也是結點)
Node getNamedItem(String name)
檢索通過名稱指定的節點。
或
Node item(int index)
返回映射中第 index 個項。
最后,對返回的屬性通過以下方法獲取名、值:(屬性也是結點)
String getNodeName()
此節點的名稱,取決於其類型;
String getNodeValue()
此節點的值,取決於其類型;
7:獲取結點的子節點列表:
NodeList getChildNodes()
包含此節點的所有子節點的 NodeList。
8:獲取結點值:
String getNodeName()
此節點的名稱,取決於其類型;
String getNodeValue()
此節點的值,取決於其類型;
總結:DOM方法解析XML文檔,把元素、元素屬性、元素值都看作Node類型,通過node.getNodeName()獲取元素名、屬性名,
通過getNodeValue()獲取屬性值、元素值,通過getChildNodes()獲取子節點們,通過item(i)獲取第i個屬性或者第i個子節點。
二:SAX方法
Java原生的XML解析方法之二——SAX方法,原理:通過parse(file,listener)函數用一個listener對xml文件進行查找,按順序讀取文檔,遍歷每個標簽,當發現目標標簽
時,讀取標簽的屬性、結點值等信息並返回。
優點:
a、無需將整個xml文檔載入內存,因此消耗內存少
b、可以繼承ContentHandler創建多個執行不同查詢的listener進行解析操作
缺點:
a、不能隨機的訪問xml中的節點
b、不能修改文檔
c、查詢依次就要對XML文檔從頭到尾遍歷一次
操作步驟:
1:創建解析工廠:SAXParserFactory factory = SAXParserFactory.newInstance();
2:由工廠創建解析器:SAXParser parser = factory.newSAXParser();
3:通過解析器的parse()方法,對指定xml文檔以指定handler之類進行解析查詢:parser.parse(xmlFile, new MySaxListener());
我們要繼承DefaultHandler類,定義相應的查詢操作類:
1:重寫父類中的文檔開始方法、文檔結束方法,定義開始、結束遍歷xml文檔時的操作:
void startDocument()
接收文檔開始的通知。
void endDocument()
接收文檔結束的通知。
2:重寫父類的標簽開始方法、標簽結束方法,定義遍歷到一個開始、結束標簽時的操作:
void startElement(String uri, String localName, String qName, Attributes attributes) //參數qName是標簽名、attributes是屬性列表
接收元素開始的通知。
void endElement(String uri, String localName, String qName)
接收元素結束的通知。
3:重寫characters(char[] ch, int start, int length)方法:
// 對事件發生時,元素的字符怎么處理
public void characters(char[] ch, int start, int length) throws SAXException {
//參數ch是當上述4中事件隨便一個發生時,對應的元素的值,值在ch中start開始,length長。從頭到尾遍歷整個xml文檔時,每個標簽的值依次被存入ch中。
}
也就是說,通過SAX解析xml文檔是沒有dom對象出現的,所以不會有node,不會有getNodeName()、getNodeValue()獲取結點名、值。
總結:SAX解析XML文檔的結點名是通過事件函數的參數qName獲取的,屬性是通過參數attributes的getValue("屬性名")獲取的,
結點值是通過當前事件函數發生時,characters(char[] ch, int start, int length)方法中的內容獲取的。
三:JDOM方法
JDOM方法是根據DOM方法的眾多繁瑣操作進行包裝得到的,上面我們看到,DOM方法解析XML文檔其實是很繁瑣的,而且很混亂,標簽、屬性、換行空格都當作結點類型來處理。JDOM方法定義了一系列通俗、好記的方法來解析XML,方法的底層封裝了一系列DOM操作,但是我們不必親自去進行這些繁瑣的工作了。
優點:
a、DOM方式的優點:查找方便,可以修改
缺點
a、DOM方式的缺點:裝載整個文檔,對內存容量要求高
在JDOM中,同一了根節點、普通結點、屬性等全為Element類型。
操作步驟:
1:創建一個SAXbuilder:SAXBuilder builder = new SAXBuilder();
2:創建文件輸入流打開xml文件:InputStream in = new FileInputStream("XXX.xml");
3:通過builder,從輸入流讀取xml文件創建dom對象:Document dom = builder.build(in);
4:獲取根節點:Element root=dom.getRootElement();
5:獲取子節點列表:List<Element> childNodes = node.getChildren();
6:遍歷子節點列表,獲取第i個結點:Element node = childNodes.get(i);
7:讀取結點信息:
1)結點屬性值:node.getAttributeValue("屬性名");
2)結點名:node.getName();
3)結點值:node.getValue();
4)子結點文本值:node.getChildText("子結點名");
四:DOM4J方法
Dom4j是目前最流行、最好用的XML解析工具,解析XML的速度最快。
操作步驟:
1:創建SAXReader:SAXReader reader = new SAXReader();
2:創建文件輸入流打開xml文件:InputStream in = new FileInputStream("XXX.xml");
3:通過reader和輸入流讀取xml文件到內存創建Document對象:Document dom = reader.read(in);
4:獲取根節點:Element root=dom.getRootElement();
5:獲取子節點列表:List<Element> childNodes = root.elements();
6:遍歷子節點:Element node = childNodes.get(i);
7:讀取結點信息:
1)結點屬性值:node.attributeValue("屬性名");
2)結點名:node.getName();
3)結點值:node.getValue();
4)子結點文本值:node.elementText("子結點名")
總結:
1)DOM、JDOM、DOM4j都是把xml文檔讀取到內存中,生成dom對象進行遍歷的;
DOM是Java原生的,所以比較繁瑣;
JDOM是對DOM操作的封裝,更加通俗、易記,操作也快了一點;
DOM4j解析xml的函數上與JDOM差不多,只不過有幾個相同功能的函數名字不同而已,過程都是一樣的;但由於底層使用了Xpath等方法加快了索引,所以檢索性能更快。
2)SAX是基於事件驅動的,查詢事件監聽器繼承自DefaultHandler,定義了檢索xml過程中遇到開始標簽、結束標簽時執行的事件函數,從而查找需要的信息並返回而不是把整個文檔都加載進來。
