java、Dom4j、循环迭代递归解析XML,不论是否是叶子节点、有复合结构

网上有很多Dom4j 解析xml的java代码,但是都忒简单了啊!
关键是大多都是知道xml嵌套了几层的情况下,但是大多数时候都没有那么简单啊!
先贴一个简单的方法,附上解析用的简单xml


<bookstore>
    <book id="1">
        <name>冰与火之歌name>
        <author>乔治马丁author>
        <year>2014year>
        <price>89price>
    book>
    <book id="2">
        <name>安徒生童话name>
        <year>2004year>
        <price>77price>
        <language>Englishlanguage>
    book>    
bookstore>

XML

以下是dom4j的迭代器Iterator 方法解析

public class DOM4JTest {
    private static ArrayList bookList = new ArrayList();
    /**
     * @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 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();
        }
    }
}

上面方法清晰又有效,运行结果是
java、Dom4j、循环迭代递归解析XML,不论是否是叶子节点、有复合结构_第1张图片

但是如果我把xml稍微改一下


<bookstore>
    <book id="1">

        <name>冰与火之歌name>
        <author>乔治马丁author>
        <year>2014year>
        <price>
            <YMB>89YMB>
            <DOL>14DOL>
        price>
    book>
    <book id="2">
        <name>安徒生童话name>
        <year>2004year>
        <price>77price>
        <language>Englishlanguage>
    book>    
bookstore>

运行结果就会变成
java、Dom4j、循环迭代递归解析XML,不论是否是叶子节点、有复合结构_第2张图片

那肯定不行啊。。。
所以 写了一个 循环迭代递归的 不论是否有叶子节点的 也不管你这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());
        }
    }
}

以下是运行结果
java、Dom4j、循环迭代递归解析XML,不论是否是叶子节点、有复合结构_第3张图片

可能在输出上稍微欠佳,可以再优化一下
但是至少做到了不论xml是什么格式,嵌套了多少层,都能获取到 节点名和节点值了

你可能感兴趣的:(java)