1. 程式人生 > >DOM,SAX,JDOM,DOM4J優缺點比較及生產xml和解析xml

DOM,SAX,JDOM,DOM4J優缺點比較及生產xml和解析xml

下載必要的jar包:

activation.jar
commons-logging-1.0.4.jar
dom4j-1.6.1.jar
jaxen-1.1.1.jar
jdom-1.0.jar

一、DOM

解析器讀入整個文件,然後構建一個駐留記憶體的樹結構,使用 DOM 介面來操作這個樹結構。

優點:整個文件樹在記憶體中,便於操作;支援刪除、修改、重新排列等多種功能;訪問效率高。

缺點:將整個文件調入記憶體(包括無用的節點),浪費時間和空間;使用場合:一旦解析了文件還需多次訪問這些資料;硬體資源充足(記憶體、CPU)

package xmlParse;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Calendar;
import java.util.Locale;
import java.util.TimeZone;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.Result;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 * java自帶的dom解析xml檔案
 * 
 * @author abc
 * 
 */
public class TestDom {
	public static void main(String[] args) {
		builXmlByDom();
		parseXmlByDom();
	}
	/**
	 * 生成xml資訊
	 */
	public static void builXmlByDom() {
		long begintime = System.currentTimeMillis();
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		try {
			//構建Document
			DocumentBuilder db = dbf.newDocumentBuilder();
			Document doc=db.newDocument();
			Element root=doc.createElement("students");
			root.setAttribute("class", "一班");
			root.setAttribute("count", "3");
			
			Element stu=doc.createElement("student");
			Element name=doc.createElement("name");
			name.appendChild(doc.createTextNode("小明"));
			Element age=doc.createElement("age");
			age.appendChild(doc.createTextNode("10"));
			stu.appendChild(name);
			stu.appendChild(age);
			root.appendChild(stu);
			
			
			 stu=doc.createElement("student");
			 stu.setAttribute("position","班長");
			 name=doc.createElement("name");
			 name.appendChild(doc.createTextNode("小王"));
			 age=doc.createElement("age");
			 age.appendChild(doc.createTextNode("11"));
			 stu.appendChild(name);
			 stu.appendChild(age);
			 root.appendChild(stu);

			 stu=doc.createElement("student");
			 name=doc.createElement("name");
			 name.appendChild(doc.createTextNode("小兵"));
			 age=doc.createElement("age");
		     age.appendChild(doc.createTextNode("12"));
			 stu.appendChild(name);
			 stu.appendChild(age);
			 root.appendChild(stu);
			 
			 doc.appendChild(root);
			 //將被變換的Document物件封裝到一個DOMSource物件中
			 DOMSource xmlSource=new DOMSource(doc);
			 //使用 Transformer物件將一個Document節點變換為一個XML檔案
			 TransformerFactory transFactory=TransformerFactory. newInstance();
			 Transformer transformer=transFactory.newTransformer();
			 
			 //建立Result
			 File file=new File("students.xml");
			 FileOutputStream fos;
			 fos = new FileOutputStream(file);
			 StreamResult result=new StreamResult(fos);
			 transformer.transform(xmlSource, result);
			 if(fos!=null){
				 fos.close();
			 }
		}catch (ParserConfigurationException e) {
			e.printStackTrace();
		}catch (TransformerConfigurationException e) {
			e.printStackTrace();
		}catch (FileNotFoundException e) {
			e.printStackTrace();
		}catch (TransformerException e) {
			e.printStackTrace();
		}catch (IOException e) {
			e.printStackTrace();
		}  
		System.out.println("dom生成時間(毫秒)"
				+ (System.currentTimeMillis() - begintime));
	}
	/**
	 * 解析xml資訊
	 */
	public static void parseXmlByDom() {
		long begintime = System.currentTimeMillis();;
		try {
			DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
			DocumentBuilder builder=dbf.newDocumentBuilder();
			File file=new File("students.xml");
			Document doc=builder.parse(file);
			NodeList students=doc.getFirstChild().getChildNodes();
			Node student=null;
			Node node=null;
			for(int i=0,len=students.getLength();i<len;i++){
				student=students.item(i);
				NodeList childs=student.getChildNodes();
				System.out.println("第"+(i+1)+"個學生");
				for(int j=0,size=childs.getLength();j<size;j++){
					node=childs.item(j);
					if("name".equals(node.getNodeName())){
						System.out.println(node.getNodeName()+"---"+node.getTextContent());
					}
					if("age".equals(node.getNodeName())){
						System.out.println(node.getNodeName()+"---"+node.getTextContent());
					}
				}
			}
		} catch (DOMException e) {
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		System.out.println("dom解析時間(毫秒)"
				+ (System.currentTimeMillis() - begintime));
	}
}

二、SAX

特點:  1、邊讀邊解析,應用於大型XML文件

              2、只支援讀

              3、訪問效率低

              4、順序訪問

package xmlParse;

import java.io.File;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

public class TestSAXParse {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		sax();
	}

	public static void sax() {
		long begintime = System.currentTimeMillis();
		File f = new File("students.xml");
		SAXParserFactory sf = SAXParserFactory.newInstance();
		try {
			SAXParser sp = sf.newSAXParser();
			SAXHandler handler = new SAXHandler();
			sp.parse(f, handler);
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println("sax解析時間(毫秒)"
				+ (System.currentTimeMillis() - begintime));

	}
}



SAXHandler.java
package xmlParse;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import java.util.Stack;
public class SAXHandler extends DefaultHandler {
	Stack tags = null;
	@Override
	public void startDocument() throws SAXException {
		tags=new Stack();
	}

	@Override
	public void endDocument() throws SAXException {
		while(!tags.isEmpty()){
			System.out.println(tags.peek());
			tags.pop();
		}
		tags=null;
	}

	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		if("students".equals(qName)){
			System.out.println(attributes.getValue("class")+"--人數-"+attributes.getValue("count"));
		}
		tags.push(qName);//壓入棧
	}

	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		tags.pop();//取出棧頂元素
	}

	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		String tag=(String) tags.peek();//檢視棧頂元素,但不移除
		if("name".equals(tag)){
			System.out.println("name==="+new String(ch,start,length));
		}
		if("age".equals(tag)){
			System.out.println("age==="+new String(ch,start,length));
		}
	}

}


三、JDOM

JDOM
優點:①是基於樹的處理XML的Java API,把樹載入在記憶體中
     ②沒有向下相容的限制,因此比DOM簡單
     ③速度快,缺陷少
     ④具有SAX的JAVA規則
缺點:①不能處理大於記憶體的文件
     ②JDOM表示XML文件邏輯模型。不能保證每個位元組真正變換。
     ③針對例項文件不提供DTD與模式的任何實際模型。
     ④不支援與DOM中相應遍歷包
最適合於:JDOM具有樹的便利,也有SAX的JAVA規則。在需要平衡時使用

JDOM


package xmlParse;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;

public class TestJDOM {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		buildXmlByJDOM();
		parseXmlByJDOM();
	}
	
	public static String buildXmlByJDOM(){
		Document doc=new Document();
		Element root=new Element("students");
		root.setAttribute("count", "3");
		root.setAttribute("class", "一班");
		doc.setRootElement(root);
		root.addContent(new Element("student").addContent(new Element("name").setText("小明"))
				.addContent(new Element("age").setText("10")));
		root.addContent(new Element("student").addContent(new Element("name").setText("小汪"))
			    .addContent(new Element("age").setText("11")));
		root.addContent(new Element("student").addContent(new Element("name").setText("小兵"))
				.addContent(new Element("age").setText("12")));
		ByteArrayOutputStream out=new ByteArrayOutputStream();
		XMLOutputter putter=new XMLOutputter();
		try {
			putter.output(doc, out);
			putter.output(doc, new FileOutputStream("students.xml"));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return out.toString();
	}
   public static void parseXmlByJDOM(){
	   long begintime=System.currentTimeMillis();
	   File f=new File("students.xml");  
	   SAXBuilder builder=new SAXBuilder();
	   try {
		Document doc=builder.build(new FileInputStream(f));
		Element root=doc.getRootElement();
		System.out.println(root.getAttributeValue("class")+"-人數:--"+root.getAttributeValue("count"));
		
		List list=root.getChildren("student");
		for(int i=0;i<list.size();i++){
			Element ele=(Element)list.get(i);
			System.out.println("第"+(i+1)+"個學生");
			System.out.println(ele.getChildText("name")+"---"+ele.getChildText("age"));
		}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (JDOMException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	    System.out.println("sax解析時間(毫秒)"+(System.currentTimeMillis()-begintime));
   }
}

四、DOM4J

DOM4J 是一個非常非常優秀的Java XML API,具有效能優異、功能強大和極端易用使用的特點,同時它也是一個開放原始碼的軟體。如今你可以看到越來越多的 Java 軟體都在使用 DOM4J 來讀寫 XML,特別值得一提的是連 Sun 的 JAXM 也在用 DOM4J。 

DOM4J
package xmlParse;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

public class TestDom4J {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		buildXmlByDOM4J();
		paserXmlByDOM4J();
	}
	public static void buildXmlByDOM4J(){
		Document doc=DocumentHelper.createDocument();
		doc.setXMLEncoding("UTF-8");
		Element root=doc.addElement("students");
		root.addAttribute("class", "一班").addAttribute("count", "3");
		Element student=root.addElement("student");
		student.addElement("name").setText("小明");
		student.addElement("age").setText("10");
		
		student=root.addElement("student").addAttribute("position", "班長");
		student.addElement("name").setText("小汪");
		student.addElement("age").setText("11");
	
		student=root.addElement("student");
		student.addElement("name").setText("小兵");
		student.addElement("age").setText("12");
		
		String xmlStr=doc.asXML();
		try {
			OutputFormat format=OutputFormat.createPrettyPrint();
			XMLWriter writer=new XMLWriter(new FileWriter(new File("students.xml")),format);
			writer.setEscapeText(false);
			writer.write(xmlStr);
			writer.close();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}catch (IOException e) {
			e.printStackTrace();
		}
	}
	public static void paserXmlByDOM4J(){
		  long begintime=System.currentTimeMillis();
		  SAXReader reader=new SAXReader();
		  try {
			Document doc=reader.read(new FileInputStream(new File("students.xml")));
			Element root=doc.getRootElement();
			System.out.println(root.attributeValue("class")+"--人數--"+root.attributeValue("count"));
	/*		List<Node> list=root.selectNodes("student");//需要引入jaxen-1.1.1.jar
			for(int i=0,len=list.size();i<len;i++){
				Node node=(Node)list.get(i);
				System.out.println(node.selectSingleNode("name").getText()+"---"+node.selectSingleNode("age").getStringValue());
			}*/
			Iterator it=root.elementIterator();
			Element ele;
			while(it.hasNext()){
				ele=(Element)it.next();
				//System.out.println(ele.selectSingleNode("name").getText()+"---"+ele.selectSingleNode("age").getText());
				System.out.println(ele.elementText("name")+"---"+ele.elementText("age"));
			}
		  } catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (DocumentException e) {
			e.printStackTrace();
		}
		  
		  System.out.println("sax解析時間(毫秒)"+(System.currentTimeMillis()-begintime));
	}
}