1. 程式人生 > >java解析xml方法詳解

java解析xml方法詳解

首言

java中解析xml檔案有四種方式,分別是DOM、SAX、JDOM、DOM4J,這四種前兩種是系統自帶的,後兩種需要匯入jar包,其中先要對xml檔案有一個基本的瞭解。xml檔案是為了不同程式,不同平臺之間資料傳輸,不同資料平臺的資料共享的作用。是以樹形結構的儲存的。XML 被設計用來傳輸和儲存資料,其焦點是資料的內容。DOM解析

1)DOM(JAXP Crimson解析器) 

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

DOM解析
節點型別               named constant  nodeName()的返回值   nodeValue()的返回值
name  ELEMENT_NODE element name   null
Attr  ATTRIBUTE_NODE  屬性名稱 屬性值
text TEXT_NODE #text    節點內容

package project_xml;
 
import java.io.File;
import java.io.IOException;
 
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
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.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
 
public class xml_dom {
 
	public static void main(String[] args) {
	    xml_dom xml_dom1=new xml_dom();
	   xml_dom1.xml_dom_parse();
	    //xml_dom1.creat_xml();
	}
	
	
	 public void xml_dom_parse() {
		   DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
			try {
				DocumentBuilder db=dbf.newDocumentBuilder();
				Document docu=db.parse("book.xml");
				//獲取所有的書籍節點
	           NodeList booklist=docu.getElementsByTagName("book");
	           for(int i =0;i<booklist.getLength();i++){
	           	Node book_item=booklist.item(i);
	           	System.out.println("第"+(i+1)+"本書");
	           	NamedNodeMap node_att=book_item.getAttributes();//讀取屬性,並存在一個<span style="font-family: Arial, Helvetica, sans-serif;">NamedNodeMap中</span>
	           	for(int j=0;j<node_att.getLength();j++){
	           		Node node=node_att.item(j);
	           		System.out.print(node.getNodeName()+":"+node.getNodeValue()+" ");
	           		System.out.println();
	           	}
	           	NodeList book_child=book_item.getChildNodes();
	           	for(int k=0;k<book_child.getLength();k++){
	           		Node book_child_ele=book_child.item(k);
	           		if(book_child_ele.getNodeType()==Node.ELEMENT_NODE){//如果沒有會打印出很多空格,因為text也是一種節點型別,
	           			//System.out.println(book_child_ele.getNodeName()+":"+book_child_ele.getFirstChild().getNodeValue());
	           			////這個就是採集到這個<name></name>中所有的所有的text
	           			System.out.println(book_child_ele.getNodeName()+":"+book_child_ele.getTextContent());
	           		}
	           	}
	           	System.out.println("以上就是第"+(i+1)+"本書");
	           	
	           	
	           }
			} catch (ParserConfigurationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (SAXException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	 
	 public void creat_xml() {
		try {
			DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
			DocumentBuilder db=dbf.newDocumentBuilder();
			Document document=db.newDocument();
			//可以將standalone設定為true,這樣就不會顯示了,表示的意思是不需要說明文件
			document.setXmlStandalone(true);
			Element bookstore=document.createElement("bookstore");
			Element book=document.createElement("book");
			Element name=document.createElement("name");
			name.setTextContent("安徒生童話");
			book.setAttribute("id", "1");
			book.setAttribute("size", "lower");
			book.appendChild(name);
			bookstore.appendChild(book);
			document.appendChild(bookstore);
			TransformerFactory tf=TransformerFactory.newInstance();
			Transformer transformer=tf.newTransformer();
			transformer.setOutputProperty(OutputKeys.INDENT, "yes");
			transformer.transform(new DOMSource(document), new StreamResult(new File("book1.xml")));
		} catch (ParserConfigurationException  e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (TransformerConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (TransformerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
}
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
	<book id="1" size="medium">
		<name >安徒生童話</name>
		<price>89</price>
		<language>英文</language>
		<year>2004</year>
	</book>
	<book id="2" size="lower">
		<name>一千零一夜</name>
		<price>65</price>
		<language>日語</language>
		<year>2014</year>
	</book>
	<book id="3" size="large">
		<name>美好</name>
		<price>99</price>
		<language>中文</language>
		<year>2015</year>
	</book>
</bookstore>

2)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 dom4j_xml {
 
	public static void main(String[] args) {
		// TODO Auto-generated method stub
             dom4j_xml a=new dom4j_xml();
             a.creat_dom4j();
	}
	
	
	public void DOM4J_xml() {
		int book_index=0;
	      try {
	    	  SAXReader reader=new SAXReader();
			Document document=reader.read(new File("book.xml"));
			Element book_root=document.getRootElement();
			Iterator iterator=book_root.elementIterator();
			while(iterator.hasNext()){
				book_index++;
				Element book=(Element)iterator.next();
				List<Attribute> book_attr=book.attributes();
				for (Attribute attribute : book_attr) {
					System.out.println(attribute.getName()+":"+attribute.getValue());
				}
				Iterator book_node_iter=book.elementIterator();
				while(book_node_iter.hasNext()){
					Element book_node=(Element)book_node_iter.next();
					System.out.println(book_node.getName()+":"+book_node.getStringValue());
				}
				System.out.println("============第"+(book_index)+"本結束==========");
			}
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	      
	}
	
	public void creat_dom4j() {
		Document document=DocumentHelper.createDocument();
		Element element_rss=document.addElement("rss");
		element_rss.addAttribute("version", "2.0");
		Element element_channel=element_rss.addElement("channel");
		Element element_title=element_channel.addElement("title");
		element_title.setText("我們是愛好啥打法和");
		OutputFormat format=OutputFormat.createPrettyPrint();
		//format.setEncoding("");
		try {
			XMLWriter writer=new XMLWriter(new FileOutputStream(new File("rss.xml")), format);
			//write中的方法,可以設定是否轉義字元
			writer.setEscapeText(false);
		    writer.write(document);
		    writer.close();
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
 
}

建立SAXReader的物件reader,用過reader物件的read方法載入book,xml檔案,並獲取document物件
通過document物件獲取根節點的bookstores,通過element物件的elementIterator方法獲取迭代器
遍歷迭代器,獲取根節點中的資訊,獲取節點時可以通過迭代器再迭代下就可以了

比較

1)DOM4J效能最好,連Sun的JAXM也在用DOM4J。目前許多開源專案中大量採用DOM4J,例如大名鼎鼎的Hibernate也用DOM4J來讀取XML配置檔案。如果不考慮可移植性,那就採用DOM4J.

2)JDOM和DOM在效能測試時表現不佳,在測試10M文件時記憶體溢位。在小文件情況下還值得考慮使用DOM和JDOM。雖然JDOM的開發者已經說明他們期望在正式發行版前專注效能問題,但是從效能觀點來看,它確實沒有值得推薦之處。另外,DOM仍是一個非常好的選擇。DOM實現廣泛應用於多種程式語言。它還是許多其它與XML相關的標準的基礎,因為它正式獲得W3C推薦(與基於非標準的Java模型相對),所以在某些型別的專案中可能也需要它(如在JavaScript中使用DOM)。

3)SAX表現較好,這要依賴於它特定的解析方式-事件驅動。一個SAX檢測即將到來的XML流,但並沒有載入到記憶體(當然當XML流被讀入時,會有部分文件暫時隱藏在記憶體中)。