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使用起來也要簡單得多。
節點型別 | 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流被讀入時,會有部分文件暫時隱藏在記憶體中)。