在 java 中使用 Dom4j 解析 XML
對 XML 文件的解析,通常使用的是 Dom4j 和 jdom 作為XML解析工具。
在此只介紹下 Dom4j 對 XML 文件的解析使用方法。
1. 明白了解 XML 文件的樹結構
2. 了解 DOM4J 的一些接口
1. XML 文件的樹結構(附:XML :http://www.w3school.com.cn/xml/xml_tree.asp)
XML 文檔形成一種樹結構
XML 文檔必須包含根元素。該元素是所有其他元素的父元素。
XML 文檔中的元素形成了一棵文檔樹。這棵樹從根部開始,並擴展到樹的最底端。
所有元素均可擁有子元素:
1 <root> 2 <child> 3 <subchild>.....</subchild> 4 </child> 5 </root>
父、子以及同胞等術語用於描述元素之間的關系。父元素擁有子元素。相同層級上的子元素成為同胞(兄弟或姐妹)。
所有元素均可擁有文本內容和屬性(類似 HTML 中)。
實例:
上圖表示下面的 XML 中的一本書:
1 <bookstore> 2 <book category="COOKING"> 3 <title lang="en">Everyday Italian</title> 4 <author>Giada De Laurentiis</author> 5 <year>2005</year> 6 <price>30.00</price> 7 </book> 8 <book category="CHILDREN"> 9 <title lang="en">Harry Potter</title> 10 <author>J K. Rowling</author> 11 <year>2005</year> 12 <price>29.99</price> 13 </book> 14 <book category="WEB"> 15 <title lang="en">Learning XML</title> 16 <author>Erik T. Ray</author> 17 <year>2003</year> 18 <price>39.95</price> 19 </book> 20 </bookstore>
例子中的根元素是 <bookstore>。文檔中的所有 <book> 元素都被包含在 <bookstore> 中。
<book> 元素有 4 個子元素:<title>、< author>、<year>、<price>。
所以,對 XML 文件的解析,無非就是從 XML 文件中獲取到根元素與子元素。
對此 Dom4j 已經對一些需要使用的方法進行了封裝。
2. 了解DOM4J的一些接口 (附:http://www.blogjava.net/i369/articles/154264.html)
- 讀取並解析XML文檔:
1 // 從文件讀取XML,輸入文件名,返回XML文檔 2 public Document read(String fileName) throws MalformedURLException, DocumentException { 3 SAXReader reader = new SAXReader(); 4 Document document = reader.read(new File(fileName)); 5 return document; 6 }
其中,reader的read方法是重載的,可以從InputStream, File, Url等多種不同的源來讀取。得到的Document對象就帶表了整個XML。
2. 取得 root 結點
1 public Element getRootElement(Document doc){ 2 return doc.getRootElement(); 3 } 4
使用 getRootElement 直接可以返回root結點.
3. 遍歷 XML 樹
DOM4J提供至少3種遍歷節點的方法,在此只取兩種方法進行記錄.
1) 枚舉
1 // 枚舉所有子節點 2 for ( Iterator i = root.elementIterator(); i.hasNext(); ) { 3 Element element = (Element) i.next(); 4 // do something 5 } 6 // 枚舉名稱為foo的節點 7 for ( Iterator i = root.elementIterator(foo); i.hasNext();) { 8 Element foo = (Element) i.next(); 9 // do something 10 } 11 // 枚舉屬性 12 for ( Iterator i = root.attributeIterator(); i.hasNext(); ) { 13 Attribute attribute = (Attribute) i.next(); 14 // do something 15 }
2) 遞歸
1 public void treeWalk() { 2 treeWalk(getRootElement()); 3 } 4 public void treeWalk(Element element) { 5 for (int i = 0, size = element.nodeCount(); i < size; i++) { 6 Node node = element.node(i); 7 if (node instanceof Element) { 8 treeWalk((Element) node); 9 } else { // do something.... 10 } 11 } 12 }
附:
Attribute
|
Attribute定義了XML的屬性
|
Branch
|
Branch為能夠包含子節點的節點如XML元素(Element)和文檔(Docuemnts)定義了一個公共的行為,
|
CDATA
|
CDATA 定義了XML CDATA 區域
|
CharacterData
|
CharacterData是一個標識借口,標識基於字符的節點。如CDATA,Comment, Text.
|
Comment
|
Comment 定義了XML注釋的行為
|
Document
|
定義了XML文檔
|
DocumentType
|
DocumentType 定義XML DOCTYPE聲明
|
Element
|
Element定義XML 元素
|
ElementHandler
|
ElementHandler定義了 Element 對象的處理器
|
ElementPath
|
被
ElementHandler 使用,用於取得當前正在處理的路徑層次信息
|
Entity
|
Entity定義 XML entity
|
Node
|
Node為所有的dom4j中XML節點定義了多態行為
|
NodeFilter
|
NodeFilter 定義了在dom4j節點中產生的一個濾鏡或謂詞的行為(predicate)
|
ProcessingInstruction
|
ProcessingInstruction 定義 XML 處理指令.
|
Text
|
Text 定義XML 文本節點.
|
Visitor
|
Visitor 用於實現Visitor模式.
|
XPath
|
XPath 在分析一個字符串后會提供一個XPath 表達式
|
實例:附:)http://www.cnblogs.com/nerxious/archive/2013/05/04/3060263.html
在使用過程中需要下載: DOM4J*點擊下載
首先我們需要出創建一個xml文檔,然后才能對其解析
XML文檔:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <HD> 3 <disk name="C"> 4 <capacity>8G</capacity> 5 <directories>200</directories> 6 <files>1580</files> 7 </disk> 8 9 <disk name="D"> 10 <capacity>10G</capacity> 11 <directories>500</directories> 12 <files>3000</files> 13 </disk> 14 </HD>
示例一:用List列表的方式來解析xml
1 package dom; 2 3 import java.io.File; 4 import java.util.List; 5 import org.dom4j.Document; 6 import org.dom4j.Element; 7 import org.dom4j.io.SAXReader; 8 9 10 public class Demo { 11 12 public static void main(String[] args) throws Exception { 13 SAXReader reader = new SAXReader(); 14 File file = new File("test.xml"); 15 Document document = reader.read(file); 16 Element root = document.getRootElement(); 17 List<Element> childElements = root.elements(); 18 for (Element child : childElements) { 19 //未知屬性名情況下 20 /*List<Attribute> attributeList = child.attributes(); 21 for (Attribute attr : attributeList) { 22 System.out.println(attr.getName() + ": " + attr.getValue()); 23 }*/ 24 25 //已知屬性名情況下 26 System.out.println("name: " + child.attributeValue("name")); 27 28 //未知子元素名情況下 29 /*List<Element> elementList = child.elements(); 30 for (Element ele : elementList) { 31 System.out.println(ele.getName() + ": " + ele.getText()); 32 } 33 System.out.println();*/ 34 35 //已知子元素名的情況下 36 System.out.println("capacity: " + child.elementText("capacity")); 37 System.out.println("directories: " + child.elementText("directories")); 38 System.out.println("files: " + child.elementText("files")); 39 //這行是為了格式化美觀而存在 40 System.out.println(); 41 } 42 } 43 44 }
示例二:使用Iterator迭代器的方式來解析xml
1 package dom; 2 3 import java.io.File; 4 import java.util.Iterator; 5 import org.dom4j.Document; 6 import org.dom4j.Element; 7 import org.dom4j.io.SAXReader; 8 9 public class Demo1 { 10 public static void main(String[] args) throws Exception { 11 SAXReader reader = new SAXReader(); 12 Document document = reader.read(new File("test.xml")); 13 Element root = document.getRootElement(); 14 15 Iterator it = root.elementIterator(); 16 while (it.hasNext()) { 17 Element element = (Element) it.next(); 18 19 //未知屬性名稱情況下 20 /*Iterator attrIt = element.attributeIterator(); 21 while (attrIt.hasNext()) { 22 Attribute a = (Attribute) attrIt.next(); 23 System.out.println(a.getValue()); 24 }*/ 25 26 //已知屬性名稱情況下 27 System.out.println("name: " + element.attributeValue("name")); 28 29 //未知元素名情況下 30 /*Iterator eleIt = element.elementIterator(); 31 while (eleIt.hasNext()) { 32 Element e = (Element) eleIt.next(); 33 System.out.println(e.getName() + ": " + e.getText()); 34 } 35 System.out.println();*/ 36 37 //已知元素名情況下 38 System.out.println("capacity: " + element.elementText("capacity")); 39 System.out.println("directories: " + element.elementText("directories")); 40 System.out.println("files: " + element.elementText("files")); 41 System.out.println(); 42 } 43 } 44 }
示例三:創建xml文檔並輸出到文件
1 package dom; 2 3 import java.io.File; 4 import java.io.FileOutputStream; 5 6 import org.dom4j.Document; 7 import org.dom4j.DocumentHelper; 8 import org.dom4j.Element; 9 import org.dom4j.io.OutputFormat; 10 import org.dom4j.io.XMLWriter; 11 12 13 public class Demo2 { 14 public static void main(String[] args) throws Exception { 15 Document doc = DocumentHelper.createDocument(); 16 //增加根節點 17 Element HD = doc.addElement("HD"); 18 //增加子元素 19 Element disk = HD.addElement("disk"); 20 Element capacity1 = disk.addElement("capacity"); 21 Element directories1 = disk.addElement("directories"); 22 Element files1 = disk.addElement("files"); 23 24 Element disk2 = HD.addElement("disk"); 25 Element capacity2 = disk2.addElement("capacity"); 26 Element directories2 = disk2.addElement("directories"); 27 Element files2 = disk2.addElement("files"); 28 29 30 31 //為子節點添加屬性 32 disk.addAttribute("name", "C"); 33 //為元素添加內容 34 capacity1.setText("8G"); 35 directories1.setText("2000"); 36 files1.setText("1580"); 37 38 disk2.addAttribute("name", "D"); 39 //為元素添加內容 40 capacity1.setText("10G"); 41 directories1.setText("500"); 42 files1.setText("3000"); 43 44 //實例化輸出格式對象 45 OutputFormat format = OutputFormat.createPrettyPrint(); 46 //設置輸出編碼 47 format.setEncoding("UTF-8"); 48 //創建需要寫入的File對象 49 File file = new File("D:" + File.separator + "test.xml"); 50 //生成XMLWriter對象,構造函數中的參數為需要輸出的文件流和格式 51 XMLWriter writer = new XMLWriter(new FileOutputStream(file), format); 52 //開始寫入,write方法中包含上面創建的Document對象 53 writer.write(doc); 54 } 55 }
對 XML 文件的解析 和 對生成 XML 文件,關鍵在於對 XML 樹結構的理解.