網上有很多Dom4j 解析xml的java代碼,但是都忒簡單了啊!
關鍵是大多都是知道xml嵌套了幾層的情況下,但是大多數時候都沒有那麼簡單啊!
先貼一個簡單的方法,附上解析用的簡單xml
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book id="1">
<name>冰與火之歌</name>
<author>喬治馬丁</author>
<year>2014</year>
<price>89</price>
</book>
<book id="2">
<name>安徒生童話</name>
<year>2004</year>
<price>77</price>
<language>English</language>
</book>
</bookstore>
XML
以下是dom4j的迭代器Iterator 方法解析
public class DOM4JTest {
private static ArrayList<Book> bookList = new ArrayList<Book>();
/**
* @param args
*/
public static void main(String[] args) {
// 解析books.xml文件
// 創建SAXReader的對象reader
SAXReader reader = new SAXReader();
try {
// 通過reader對象的read方法加載books.xml文件,獲取docuemnt對象。
Document document = reader.read(new File("src/res/books.xml"));
// 通過document對象獲取根節點bookstore
Element bookStore = document.getRootElement();
// 通過element對象的elementIterator方法獲取迭代器
Iterator it = bookStore.elementIterator();
// 遍歷迭代器,獲取根節點中的信息(書籍)
while (it.hasNext()) {
System.out.println("=====開始遍歷某一本書=====");
Element book = (Element) it.next();
// 獲取book的屬性名以及 屬性值
List<Attribute> bookAttrs = book.attributes();
for (Attribute attr : bookAttrs) {
System.out.println("屬性名:" + attr.getName() + "--屬性值:"
+ attr.getValue());
}
Iterator itt = book.elementIterator();
while (itt.hasNext()) {
Element bookChild = (Element) itt.next();
System.out.println("節點名:" + bookChild.getName() + "--節點值:" + bookChild.getStringValue());
}
System.out.println("=====結束遍歷某一本書=====");
}
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
上面方法清晰又有效,運行結果是
但是如果我把xml稍微改一下
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book id="1">
<name>冰與火之歌</name>
<author>喬治馬丁</author>
<year>2014</year>
<price>
<YMB>89</YMB>
<DOL>14</DOL>
</price>
</book>
<book id="2">
<name>安徒生童話</name>
<year>2004</year>
<price>77</price>
<language>English</language>
</book>
</bookstore>
運行結果就會變成
那肯定不行啊。。。
所以 寫了一個 循環迭代遞歸的 不論是否有葉子節點的 也不管你這xml有多少層的 解析
裏面用到了dom4j的一個方法
public boolean hasMixedContent()
判斷是否包含混合內容。即不僅包括葉子節點也就是文本內容,也包括不是文本的子節點即嵌套節點。
package demo;
import java.io.File;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class dom4j {
public static void main(String[] args) {
// 創建SAXReader的對象reader
SAXReader reader = new SAXReader();
try {
// 通過reader對象的read方法獲取xml文件,docuemnt對象。
Document document = reader.read(new File("src/demo/books.xml"));
// 通過document對象獲取根節點
Element root = document.getRootElement();
// 循環解析
readEle(root);
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void readEle(Element e){
//判斷是否有複合內容
if(e.hasMixedContent()){
//輸出該節點的名字,對他的子節點繼續進行判斷
System.out.println("節點名:" + e.getName());
Iterator it = e.elementIterator();
while (it.hasNext()) {
Element arrrName = (Element) it.next();
//遞歸
readEle(arrrName);
}
}else{
//如果沒有複合內容,就可以輸出了
System.out.println("節點名:" + e.getName() + ",節點值:" + e.getTextTrim());
}
}
}
以下是運行結果
可能在輸出上稍微欠佳,可以再優化一下
但是至少做到了不論xml是什麼格式,嵌套了多少層,都能獲取到 節點名和節點值了