XML(1)Java解析XML的四種方法

目前在Java中用於解析XML的技術很多,主流的有DOM、SAX、JDOM、DOM4j,下文主要介紹這4種解析XML文檔技術的使用及優缺點。

先來定義一個操作xml文檔的接口XmlDocument,它定義了xml的創建與解析的接口,內容如下:

package com.interview.xml;
/***
 * @description:定義XML文檔建立與解析的接口 
 * @author xgj
 */
public interface XmlDocument {
	/** 
	* 建立XML文檔 
	*/ 
	public void createXml(String fileName); 
	/** 
	* 解析XML文檔 
	*/ 
	public void parserXml(String fileName); 
}

一、DOM

     DOM是用與平臺和語言無關的方式表示XML文檔的官方W3C標準。DOM是以層次結構組織的節點或信息片斷的集合。這個層次結構允許開發人員在樹中尋找特定信息。分析該結構通常需要加載整個文檔和構造層次結構,然後才能做任何工作。由於它是基於信息層次的,因而DOM被認爲是基於樹或基於對象的。DOM以及廣義的基於樹的處理具有幾個優點。首先,由於樹在內存中是持久的,因此可以修改它以便應用程序能對數據和結構作出更改。它還可以在任何時候在樹中上下導航,而不是像SAX那樣是一次性的處理。DOM使用起來也要簡單得多。

public class DomXml implements XmlDocument {
	private Document document;
	public void init() {
		try {
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			DocumentBuilder builder = factory.newDocumentBuilder();
			this.document = builder.newDocument();
		} catch (ParserConfigurationException e) {
			System.out.println(e.getMessage());
		}
	}

	public void createXml(String fileName) {
		Element root = this.document.createElement("xml-methods");
		this.document.appendChild(root);
		Element method = this.document.createElement("method");
		Element name = this.document.createElement("type");
		name.appendChild(this.document.createTextNode("dom"));
		method.appendChild(name);
		Element methodCreate = this.document.createElement("method-create");
		methodCreate.appendChild(this.document.createTextNode("createXml"));
		method.appendChild(methodCreate);
		Element methodParse = this.document.createElement("method-parse");
		methodParse.appendChild(this.document.createTextNode("parserXml"));
		method.appendChild(methodParse);
		root.appendChild(method);
		TransformerFactory tf = TransformerFactory.newInstance();
		try {
			Transformer transformer = tf.newTransformer();
			DOMSource source = new DOMSource(document);
			transformer.setOutputProperty(OutputKeys.ENCODING, "gb2312");
			transformer.setOutputProperty(OutputKeys.INDENT, "yes");
			PrintWriter pw = new PrintWriter(new FileOutputStream(fileName));
			StreamResult result = new StreamResult(pw);
			transformer.transform(source, result);
			System.out.println("生成XML文件成功!");
		} catch (TransformerConfigurationException e) {
			System.out.println(e.getMessage());
		} catch (IllegalArgumentException e) {
			System.out.println(e.getMessage());
		} catch (FileNotFoundException e) {
			System.out.println(e.getMessage());
		} catch (TransformerException e) {
			System.out.println(e.getMessage());
		}
	}

	public void parserXml(String fileName) {
		try {
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			Document document = db.parse(fileName);
			NodeList employees = document.getChildNodes();
			for (int i = 0; i < employees.getLength(); i++) {
				Node employee = employees.item(i);
				NodeList employeeInfo = employee.getChildNodes();
				for (int j = 0; j < employeeInfo.getLength(); j++) {
					Node node = employeeInfo.item(j);
					NodeList employeeMeta = node.getChildNodes();
					for (int k = 0; k < employeeMeta.getLength(); k++) {
						System.out.println(employeeMeta.item(k).getNodeName()
								+ ":" + employeeMeta.item(k).getTextContent());
					}
				}
			}
			System.out.println("解析完畢");
		} catch (FileNotFoundException e) {
			System.out.println(e.getMessage());
		} catch (ParserConfigurationException e) {
			System.out.println(e.getMessage());
		} catch (SAXException e) {
			System.out.println(e.getMessage());
		} catch (IOException e) {
			System.out.println(e.getMessage());
		}
	}
	
	public static void main(String[] args) {
		DomXml dom=new DomXml();
		dom.init();
		//dom.createXml("d://dom.xml");
		dom.parserXml("d://dom.xml");
	}

}

二、SAX

        SAX處理的優點非常類似於流媒體的優點。分析能夠立即開始,而不是等待所有的數據被處理。而且,由於應用程序只是在讀取數據時檢查數據,因此不需要將數據存儲在內存中。這對於大型文檔來說是個巨大的優點。事實上,應用程序甚至不必解析整個文檔;它可以在某個條件得到滿足時停止解析。一般來說,SAX還比它的替代者DOM快許多。 選擇DOM還是選擇SAX? 對於需要自己編寫代碼來處理XML文檔的開發人員來說,  選擇DOM還是SAX解析模型是一個非常重要的設計決策。 DOM採用建立樹形結構的方式訪問XML文檔,而SAX採用的事件模型。

  DOM解析器把XML文檔轉化爲一個包含其內容的樹,並可以對樹進行遍歷。用DOM解析模型的優點是編程容易,開發人員只需要調用建樹的指令,然後利用navigation APIs訪問所需的樹節點來完成任務。可以很容易的添加和修改樹中的元素。然而由於使用DOM解析器的時候需要處理整個XML文檔,所以對性能和內存的要求比較高,尤其是遇到很大的XML文件的時候。由於它的遍歷能力,DOM解析器常用於XML文檔需要頻繁的改變的服務中。

  SAX解析器採用了基於事件的模型,它在解析XML文檔的時候可以觸發一系列的事件,當發現給定的tag的時候,它可以激活一個回調方法,告訴該方法制定的標籤已經找到。SAX對內存的要求通常會比較低,因爲它讓開發人員自己來決定所要處理的tag。特別是當開發人員只需要處理文檔中所包含的部分數據時,SAX這種擴展能力得到了更好的體現。但用SAX解析器的時候編碼工作會比較困難,而且很難同時訪問同一個文檔中的多處不同數據。

public class SaxXml implements XmlDocument{

	@Override
	public void createXml(String fileName) {
		System.out.println("純SAX不提供寫xml操作");
	}

	@Override
	public void parserXml(String fileName) {
		 try {
			 SAXParserFactory factory = SAXParserFactory.newInstance();  
			 SAXParser parser = factory.newSAXParser();  
			 InputStream in = new FileInputStream(fileName);
			 parser.parse(in, new MyHandler());
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} 
	}
	
	 class MyHandler extends DefaultHandler{

		@Override
		public void endDocument() throws SAXException {
			System.out.println("解析文檔結束");
		}

		@Override
		public void startDocument() throws SAXException {
			System.out.println("開始解析文檔");
		}

		@Override
		public void startElement(String uri, String localName, String qName,
				Attributes attributes) throws SAXException {
			System.out.println("當前節點爲:"+qName);
		}
		 
	 }
	
	 public static void main(String[] args) {
		 SaxXml sax=new SaxXml();
		 sax.parserXml("d://dom.xml");
	}
}

三、JDOM    http://www.jdom.org/

       JDOM的目的是成爲Java特定文檔模型,它簡化與XML的交互並且比使用DOM實現更快。由於是第一個Java特定模型,JDOM一直得到大力推廣和促進。正在考慮通過“Java規範請求JSR-102”將它最終用作“Java標準擴展”。從2000年初就已經開始了JDOM開發。

  JDOM與DOM主要有兩方面不同。首先,JDOM僅使用具體類而不使用接口。這在某些方面簡化了API,但是也限制了靈活性。第二,API大量使用了Collections類,簡化了那些已經熟悉這些類的Java開發者的使用。

  JDOM文檔聲明其目的是“使用20%(或更少)的精力解決80%(或更多)Java/XML問題”(根據學習曲線假定爲20%)。JDOM對於大多數Java/XML應用程序來說當然是有用的,並且大多數開發者發現API比DOM容易理解得多。JDOM還包括對程序行爲的相當廣泛檢查以防止用戶做任何在XML中無意義的事。然而,它仍需要您充分理解XML以便做一些超出基本的工作(或者甚至理解某些情況下的錯誤)。這也許是比學習DOM或JDOM接口都更有意義的工作。

  JDOM自身不包含解析器。它通常使用SAX2解析器來解析和驗證輸入XML文檔(儘管它還可以將以前構造的DOM表示作爲輸入)。它包含一些轉換器以將JDOM表示輸出成SAX2事件流、DOM模型或XML文本文檔。JDOM是在Apache許可證變體下發布的開放源碼。

public class JdomXml implements XmlDocument {

	@Override
	public void createXml(String fileName) {
		Document document;
		Element root;
		root = new Element("xml-methods");
		document = new Document(root);
		Element method = new Element("method");
		root.addContent(method);
		Element type = new Element("type");
		type.setText("jdom");
		method.addContent(type);
		Element methodCreate = new Element("method-create");
		methodCreate.setText("createXml");
		method.addContent(methodCreate);
		Element amethodParsege = new Element("method-parse");
		amethodParsege.setText("parserXml");
		method.addContent(amethodParsege);
		XMLOutputter XMLOut = new XMLOutputter();
		try {
			XMLOut.output(document, new FileOutputStream(fileName));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void parserXml(String fileName) {
		try {
			SAXBuilder builder = new SAXBuilder();
			Document document = builder.build(fileName);
			Element method = document.getRootElement();
			List methodList = method.getChildren("method");
			for (int i = 0; i < methodList.size(); i++) {
				Element el = (Element) methodList.get(i);
				List info = el.getChildren();
				for (int j = 0; j < info.size(); j++) {
					System.out.println(info.get(j));
				}
			}
		} catch (JDOMException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		JdomXml jdom = new JdomXml();
		String fileName = "d://jdom.xml";
//		jdom.createXml(fileName);
		jdom.parserXml(fileName);
	}
}

四、DOM4J   http://dom4j.sourceforge.net/ 

        雖然DOM4J代表了完全獨立的開發結果,但最初,它是JDOM的一種智能分支。它合併了許多超出基本XML文檔表示的功能,包括集成的XPath支持、XML Schema支持以及用於大文檔或流化文檔的基於事件的處理。它還提供了構建文檔表示的選項,它通過DOM4J API和標準DOM接口具有並行訪問功能。從2000下半年開始,它就一直處於開發之中。

  爲支持所有這些功能,DOM4J使用接口和抽象基本類方法。DOM4J大量使用了API中的Collections類,但是在許多情況下,它還提供一些替代方法以允許更好的性能或更直接的編碼方法。直接好處是,雖然DOM4J付出了更復雜的API的代價,但是它提供了比JDOM大得多的靈活性。

  在添加靈活性、XPath集成和對大文檔處理的目標時,DOM4J的目標與JDOM是一樣的:針對Java開發者的易用性和直觀操作。它還致力於成爲比JDOM更完整的解決方案,實現在本質上處理所有Java/XML問題的目標。在完成該目標時,它比JDOM更少強調防止不正確的應用程序行爲。

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

public class Dom4jXml implements XmlDocument {

	@Override
	public void createXml(String fileName) {
		Document document = DocumentHelper.createDocument();
		Element employees = document.addElement("xml-methods");
		Element employee = employees.addElement("method");
		Element name = employee.addElement("type");
		name.setText("dom4j");
		Element methodCreate = employee.addElement("method-create");
		methodCreate.setText("createXml");
		Element amethodParsege = employee.addElement("method-parse");
		amethodParsege.setText("parserXml");
		try {
			Writer fileWriter = new FileWriter(fileName);
			XMLWriter xmlWriter = new XMLWriter(fileWriter);
			xmlWriter.write(document);
			xmlWriter.close();
		} catch (IOException e) {

			System.out.println(e.getMessage());
		}

	}

	@Override
	public void parserXml(String fileName) {
		File inputXml = new File(fileName);
		SAXReader saxReader = new SAXReader();
		try {
			Document document = saxReader.read(inputXml);
			Element employees = document.getRootElement();
			for (Iterator i = employees.elementIterator(); i.hasNext();) {
				Element employee = (Element) i.next();
				for (Iterator j = employee.elementIterator(); j.hasNext();) {
					Element node = (Element) j.next();
					System.out.println(node.getName() + ":" + node.getText());
				}

			}
		} catch (DocumentException e) {
			System.out.println(e.getMessage());
		}
		System.out.println("dom4j parserXml");
	}

	public static void main(String[] args) {
		String fileName="d://dom4j.xml";
		Dom4jXml dom4j = new Dom4jXml();
//		dom4j.createXml(fileName);
		dom4j.parserXml(fileName);
	}

}

參考文獻:
[1] http://blog.csdn.net/wwww1988600/article/details/9019785
[2] http://blog.csdn.net/jzhf2012/article/details/8532873

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章