java、Dom4j、循環迭代遞歸解析XML,不論是否是葉子節點、有複合結構

網上有很多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是什麼格式,嵌套了多少層,都能獲取到 節點名和節點值了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章