一、概述
XML全稱為可擴展的標記語言。主要用於描述數據和用作配置文件。
XML文檔在邏輯上主要由一下5個部分組成:
- XML聲明:指明所用XML的版本、文檔的編碼、文檔的獨立性信息
- 文檔類型聲明:指出XML文檔所用的DTD
- 元素:由開始標簽、元素內容和結束標簽構成
- 注釋:以<!--開始,以-->結束,用於對文檔中的內容起一個說明作用
- 處理指令:通過處理指令來通知其他應用程序來處理非XML格式的數據,格式為<?xml-stylesheet href="hello.css" type="text/css"?>
XML文檔的根元素被稱為文檔元素,它和在其外部出現的處理指令、注釋等作為文檔實體的子節點,根元素本身和其內部的子元素也是一棵樹。
二、XML文檔解析
在解析XML文檔時,通常是利用現有的XML解析器對XML文檔進行分析,應用程序通過解析器提供的API接口得到XML數據。
XML解析方式分為兩種:DOM和SAX:
DOM:用來解析相對較小的XML文件,容易增刪改查。DOM的核心是節點,DOM在解析XML文檔時,將組成文檔的各個部分映射為一個對象,這個對象就叫做節點。使用DOM解析XML文檔,需要將讀入整個XML文檔,然后在內存中創建DOM樹,生成DOM樹上的每個節點對象。
<?xml version="1.0" encoding="UTF-8"?> <書架> <書> <作者>李陽</作者> <價格>39元</價格> <出版社>高等教育出版社</出版社> </書> <書> <作者>宋吉</作者> <價格>40元</價格> <出版社>人民出版社</出版社> </書> </書架>
使用DOM解析上述XML文檔,代碼如下:
package com.test.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 org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; public class Demo { public static void main(String args[]) { //得到DOM解析器工廠類的實例 DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance(); try { //得到dom的解析器對象 DocumentBuilder db=dbf.newDocumentBuilder(); //解析XML文檔,得到代表文檔的document對象 File file=new File("D:\\Eclipse\\workSpace\\day_050401\\src\\book.xml"); Document doc=db.parse(file); //以文檔順序返回標簽名字為書的所有后代元素 NodeList nl=doc.getElementsByTagName("書"); for(int i=0;i<nl.getLength();i++) { Element elt=(Element) nl.item(i); Node eltAuthor=elt.getElementsByTagName("作者").item(0); Node eltPricer=elt.getElementsByTagName("價格").item(0); Node eltPublish=elt.getElementsByTagName("出版社").item(0); String Author=eltAuthor.getFirstChild().getNodeValue(); String Pricer=eltPricer.getFirstChild().getNodeValue(); String Publish=eltPublish.getFirstChild().getNodeValue(); System.out.println("-------書籍信息"+(i+1)+"-------"); System.out.println("作者:"+Author); System.out.println("價格:"+Pricer); System.out.println("出版社:"+Publish); } } catch (ParserConfigurationException e) { // TODO 自動生成的 catch 塊 e.printStackTrace(); } catch (SAXException e) { // TODO 自動生成的 catch 塊 e.printStackTrace(); } catch (IOException e) { // TODO 自動生成的 catch 塊 e.printStackTrace(); } } }
執行結果如下:
SAX:內存消耗較小,適合讀取操作。SAX是一種基於事件驅動的API,利用SAX解析XML文檔涉及解析器和事件處理器兩個部分。解析器負責讀取XML文檔,並向事件處理器發送事件,事件處理器則負責對事件作出相應,對傳遞的XML數據進行處理。
使用SAX解析XML文檔,代碼如下:
import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.DefaultHandler; class Book { private String name; private String author; private String price; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public String getPrice() { return price; } public void setPrice(String price) { this.price = price; } } public class Demo extends DefaultHandler { private List list=new ArrayList(); private String currentTag; private Book book; @Override public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException { currentTag=name; if("書".equals(currentTag)) { book=new Book(); } } @Override public void characters(char[] ch, int start, int length) throws SAXException { if("出版社".equals(currentTag)) { String name=new String(ch,start,length); book.setName(name); } if("作者".equals(currentTag)) { String author=new String(ch,start,length); book.setAuthor(author); } if("價格".equals(currentTag)) { String price=new String(ch,start,length); book.setPrice(price); } } @Override public void endElement(String uri, String localName, String name) throws SAXException { if(name.equals("書")) { list.add(book); book=null; } currentTag=null; } public List getBooks() { return list; } public static void main(String []args) { //1.創建解析工廠 SAXParserFactory factory=SAXParserFactory.newInstance(); SAXParser sp=null; try { //2.得到解析器 sp=factory.newSAXParser(); //3、得到讀取器 XMLReader reader=sp.getXMLReader(); File file=new File("D:\\Eclipse\\workSpace\\day_050401\\src\\book.xml"); //4.設置內容處理器 Demo handle=new Demo(); //reader.setContentHandler(handle); sp.parse(file,handle); //5.讀取xml文檔內容 List<Book> list=handle.getBooks(); for(int i=0;i<list.size();i++) System.out.println(list.get(i).getAuthor()+"----"+list.get(i).getName()+"-----"+list.get(i).getPrice()); } catch (ParserConfigurationException e) { // TODO 自動生成的 catch 塊 e.printStackTrace(); } catch (SAXException e) { // TODO 自動生成的 catch 塊 e.printStackTrace(); } catch (IOException e) { // TODO 自動生成的 catch 塊 e.printStackTrace(); } } }
運行結果如下:
三、dom4j解析XML文檔
dom4j也是一種用於解析XML文檔的開放源代碼的Java庫。下載地址http://sourceforge.net/projects/dom4j/。
使用dom4j進行讀取XMl文檔操作,代碼如下:
import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.OutputStreamWriter; import java.security.KeyStore.Entry.Attribute; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; import org.junit.Test; public class Demo { //讀取xml文件第二本書的出版社 @Test public void read() { SAXReader reader = new SAXReader(); try { Document document = reader.read("C:\\Users\\Administrator\\Desktop\\book.xml"); Element root =document.getRootElement(); Element book=(Element)root.elements("書").get(1); String value=book.element("出版社").getText(); System.out.println(value); } catch (DocumentException e) { // TODO 自動生成的 catch 塊 e.printStackTrace(); } } //在第二本書上添加一個書名:<書名>平凡的世界</書名> @Test public void add() throws DocumentException, IOException { SAXReader reader = new SAXReader(); Document document = reader.read("C:\\Users\\Administrator\\Desktop\\book.xml"); Element book=(Element) document.getRootElement().elements("書").get(1); book.addElement("書名").setText("平凡的世界"); //更新內存 XMLWriter writer = new XMLWriter(new OutputStreamWriter(new FileOutputStream("C:\\Users\\Administrator\\Desktop\\book.xml"),"UTF-8")); writer.write(document); writer.close(); } }
運行結果:
PS:如果你的項目經常需要更換解析器,建議使用DOM和SAX,這樣當更換解析器時不需要更改任何代碼,如果沒有這樣的需求,建議使用dom4j,簡單而又強大。