1. 程式人生 > >Java之DOM,SAX,JDOM,DOM4J,四種解析xml方法比較

Java之DOM,SAX,JDOM,DOM4J,四種解析xml方法比較

4種解析方式的比較
1.DOM解析   
優點:a.形成了樹結構,直觀好理解,程式碼更易編寫
         b.解析過程中樹結構保留在記憶體中,方便修改
缺點:
        a.當xml檔案較大時,對記憶體耗費比較大,容易影響解析效能並且造成記憶體溢位


2.SAX解析
優點:a.採用事件驅動模式,對記憶體耗費比較小
         b.適用於只需要處理xml中資料時
缺點:a.不易編碼(需要藉助handler來進行解析)
         b.很難同時訪問同一個xml中的多處不同資料(事件有先後順序的)


3.JDOM解析
    a.僅使用具體類而不使用介面
    b.API大量使用了Collections類


4.DOM4J
    a.JDOM的一種智慧分支,它合併了許多超出基本XML文件表示的功能
    b.DOM4J使用介面和抽象基本類方法,是一個優秀的Java XML API
    c.具有效能優異、靈活性好、功能強大和極易使用的特點

    d.是一個開原始碼的軟體

效能比較

package parserTest;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Iterator;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.SAXParserFactory;

import org.dom4j.io.SAXReader;
import org.jdom.input.SAXBuilder;
import org.junit.Test;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import handler.SAXParserHandler;
import jDomTest.Book;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;

public class ParserTest {
	@SuppressWarnings({ "unchecked", "rawtypes", "unused" })
	public void Dom4jToXML() throws Exception {
		// 解析books.xml檔案
		// 建立SAXReader的物件reader
		SAXReader reader = new SAXReader();
		// reader物件的read方法載入books.xml檔案,獲取document物件
		Document document = (Document) reader.read(new File("books.xml"));
		// 通過document物件獲取根節點bookstore
		Element bookStore = document.getRootElement();
		// 遍歷迭代器,獲取根節點中的資訊(書籍)
		Iterator it = bookStore.elementIterator();
		while (it.hasNext()) {
			//System.out.println("----------開始遍歷某本書------------");
			Element book = (Element) it.next();
			// 獲取book的屬性名和屬性值
			List<Attribute> bookAttrs = book.attributes();
			for (Attribute attr : bookAttrs) {
				//System.out.println("節點名:" + attr.getName() + "----節點值:" + attr.getValue());
			}
			Iterator itt = book.elementIterator();
			while (itt.hasNext()) {
				Element bookchild = (Element) itt.next();
				// 獲取book子節點的屬性名和屬性值
				//System.out.println("節點名:" + bookchild.getName() + "----節點值:" + bookchild.getName());
			}

			//System.out.println("----------結束遍歷某本書------------");
		}
	}

	@SuppressWarnings("unused")
	public void DomToXML() throws Exception {
		// 建立一個DocumentBuilderFactory的物件
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		// 建立一個DocumentBuilder物件
		DocumentBuilder db = dbf.newDocumentBuilder();
		// 通過DocumentBuilder物件的parse(String fileName)方法解析xml檔案
		org.w3c.dom.Document document = db.parse("books.xml");
		// 獲取所有book節點的集合
		NodeList bookList = ((org.w3c.dom.Document) document).getElementsByTagName("book");
		// 通過nodelist.getLength()方法來獲取bookList的節點個數
		//System.out.println(bookList.getLength());
		// 遍歷每一個book節點
		for (int i = 0; i < bookList.getLength(); i++) {
			//System.out.println("---------現在開始遍歷第" + (i + 1) + "本書的內容---------------");
			// 通過 item(i)方法獲取一個book節點,notelist的索引值從0開始
			Node book = bookList.item(i);
			// 獲取book節點的所有屬性集合
			NamedNodeMap attrs = book.getAttributes();
			//System.out.println("第" + (i + 1) + "本書共有" + attrs.getLength() + "個屬性");
			// 遍歷book的屬性
			for (int j = 0; j < attrs.getLength(); j++) {
				// 通過item(index)方法獲取book節點的某個屬性
				Node attr = attrs.item(j);
				// 獲取屬性名
				//System.out.print("屬性名" + attr.getNodeName());
				// 獲取屬性值
				//System.out.println("-----屬性值" + attr.getNodeValue());
			}
			// 解析book節點的子節點
			NodeList childNodes = book.getChildNodes();
			// 遍歷childNodes獲取每個節點的節點名和節點值
			//System.out.println("第" + (i + 1) + "本書共有" + childNodes.getLength() + "位元組點");
			for (int k = 0; k < childNodes.getLength(); k++) {
				// 區分出text型別的node以及element型別的node
				if (childNodes.item(k).getNodeType() == Node.ELEMENT_NODE) {
					// 獲取了element型別節點的節點名
					//System.out.print("第" + (k + 1) + "個節點的節點名為:" + childNodes.item(k).getNodeName());
					// 獲取了element型別節點的節點值
					// System.out.println("----節點值為:"+childNodes.item(k).getFirstChild().getNodeValue());
					//System.out.println("----節點值為:" + childNodes.item(k).getTextContent());
				}
			}
			//System.out.println("------------------結束遍歷-------------------");
		}
	}

	public void SAXToXML() throws Exception {
		// 獲取一個SAXParserFactory的例項
		javax.xml.parsers.SAXParserFactory factory = SAXParserFactory.newInstance();
		// 通過factory獲取SAXParser例項
		javax.xml.parsers.SAXParser parser = factory.newSAXParser();
		// 建立SAXParserHandler物件
		handler.SAXParserHandler handler = new SAXParserHandler();
		parser.parse("books.xml", handler);
	}

	@SuppressWarnings("unchecked")
	public void JDomToXML() throws Exception {
		// 進行對books.xml檔案的JDOM解析
		// 準備工作
		// 1.建立一個SAXBuilder的物件
		SAXBuilder saxBuilder = new SAXBuilder();
		// 2.建立一個輸入流,將xml檔案載入到輸入流中
		InputStream in = new FileInputStream("books.xml");
		// InputStreamReader isr= new InputStreamReader(in,"UTF-8");
		// 3.通過saxBuilder的build方法,將輸入流載入到saxBuilder中
		org.jdom.Document document = saxBuilder.build(in);
		// 4.通過document物件獲取xml檔案的根節點
		org.jdom.Element rootElement = document.getRootElement();
		// 5.獲取根節點下的子節點的List集合
		List<org.jdom.Element> bookList = ((org.jdom.Element) rootElement).getChildren();
		// 繼續進行解析
		for (org.jdom.Element book : bookList) {
			// 建立一個book物件
			Book bookEntity = new Book();
			//System.out.println("------------開始解析第" + (bookList.indexOf(book) + 1) + "本書-----------");
			// 開始解析book的屬性
			// 適用於我們不知道有多少屬性
			List<org.jdom.Attribute> attrList = book.getAttributes();
			// 適用於我們知道子節點屬性的名稱直接獲取其屬性
			// Book.getAttributeValue("id");
			// 遍歷attrList(針對於不知道book節點下屬性的名稱及數量)
			for (org.jdom.Attribute attr : attrList) {
				// 獲取屬性名
				String attrName = attr.getName();
				// 獲取屬性值
				String attrValue = attr.getValue();
				//System.out.println("屬性名:" + attrName + "-----屬性值:" + attrValue);
				if (attrName.equals("id")) {
					bookEntity.setId(attrValue);
				}
			}
			// 對book節點的子節點的節點名和節點值的遍歷
			List<org.jdom.Element> bookChilds = book.getChildren();
			for (org.jdom.Element child : bookChilds) {
				//System.out.println("節點名:" + child.getName() + "---節點值:" + child.getValue());
			}
			//System.out.println("------------結束解析第" + (bookList.indexOf(book) + 1) + "本書-----------");
		}
	}
	@Test
	public void testPerformance() throws Exception {
		System.out.println("效能測試");
		//測試DOM的效能
		long start = System.currentTimeMillis();
		DomToXML();
		System.out.println("DOM:"+(System.currentTimeMillis()-start));
		//測試SAX的效能
		start = System.currentTimeMillis();
		SAXToXML();
		System.out.println("SAX:"+(System.currentTimeMillis()-start));
		//測試JDOM的效能
		start = System.currentTimeMillis();
		JDomToXML();
		System.out.println("JDOM:"+(System.currentTimeMillis()-start));
		//測試DOM4J的效能
		start = System.currentTimeMillis();
		Dom4jToXML();
		System.out.println("DOM4J:"+(System.currentTimeMillis()-start));
	}
	public static void main(String[] args) {
		ParserTest pt = new ParserTest();
		
	}

}
截圖如下: