Java:XML篇,使用DOM4J读取并解析XML

1. 描述

Dom4j:是一个易用的、开源的库,用于XML,XPath和XSLT。它应用于Java平台,采用了Java集合框架并完全支持DOM,SAX和JAXP。据说越来越多的Java软件都在使用dom4j来读写XML,如Sun的JAXM, Hibernate等等。

需要下载最新包:dom4j-1.6.1.zip(http://sourceforge.net/projects/dom4j/),其中核心包为:dom4j-1.6.1.jar,依赖包:jaxen-1.1-beta-6.jar。
下载包中包括了API文档。目前jaxen已经有正式包下载了,参考:http://dist.codehaus.org/jaxen/distributions/
2. 示范代码

package com.clzhang.sample.xml;

import java.io.*;
import java.util.*;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.Attribute;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.VisitorSupport;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.dom4j.io.OutputFormat;

/**
 * 参考:http://sourceforge.net/projects/dom4j/,需要下载最新包:dom4j-1.6.1.zip
 * 其中核心包为:dom4j-1.6.1.jar,依赖包:jaxen-1.1-beta-6.jar。
 * 下载包中包括了API文档。
 * 目前jaxen已经有正式包下载了,参考:http://dist.codehaus.org/jaxen/distributions/
 * Dom4j是一个易用的、开源的库,用于XML,XPath和XSLT。它应用于Java平台,采用了Java集合框架并完全支持DOM,SAX和JAXP。
 * 据说越来越多的Java软件都在使用dom4j来读写XML,如Sun的JAXM, Hibernate等等。 
 * @author Administrator
 * 
 */
public class DOM4JTest {
    /**
     * 写入文件测试,这也是其它三个方法的输入;
     * 其实就是在内存中建立树,可以对树进行各种操作,增加、修改、删除,然后调用相关接口输出即可。
     * @param filename
     * @throws Exception
     */
    public void writeXMLFile(String filename) throws Exception {
        // 创建文档
        Document document = DocumentHelper.createDocument();
        
        // 获取根节点前增加子节点
        Element root = document.addElement("add");
        Element element = root.addElement("config");
        Element sub_element = element.addElement("username");
        sub_element.setText("张三");
        sub_element = element.addElement("password");
        sub_element.setText("pass");
        
        // 继续增加子节点
        element = root.addElement("doc");
        element.addAttribute("id", "1");
        sub_element = element.addElement("title");
        sub_element.setText("维护权益!");
        sub_element = element.addElement("content");
        sub_element.setText("有一个更完善的交流平台,共建美好家园");
        
        // 继续...
        element = root.addElement("doc");
        element.addAttribute("id", "2");
        sub_element = element.addElement("title");
        sub_element.setText("不维护权益!");
        sub_element = element.addElement("content");
        sub_element.setText("没有一个更完善的交流平台,不共建美好家园");

        // 格式化后输出到文件,注释掉的是输出到标准输出
        OutputFormat format = OutputFormat.createPrettyPrint();
        XMLWriter writer = new XMLWriter(new OutputStreamWriter(

                new FileOutputStream(filename), "UTF-8"), format);
//        XMLWriter writer = new XMLWriter(new OutputStreamWriter(
//                System.out, "GB2312"), format);
        writer.write(document);
        writer.close();

        System.out.println("----------------writeXMLFile调用成功!----------------");
    }

    /**
     * 其实这个解析与遍历是有些类似的, 只不过可以在调用各方法时: 
     * 1.访问节点时可以只取指定名称的节点(Node);
     * 2.访问属性时可以只取指定名称的属性(Attribute); 
     * 3.也可以直接用XPath访问一些特定的节点。
     * 
     * @param filename
     * @throws Exception
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public void parseByDOM4J(String filename) throws Exception {
        Document doc = getDocument(filename);
        Element root = doc.getRootElement();

        Iterator iterator = root.elementIterator("doc");
        while (iterator.hasNext()) {
            Element element = (Element) iterator.next();
            System.out.println("id=" + element.attribute("id").getText());

            Iterator sub_iterator = element.elementIterator(); // 或者加入参数,只取指定值
            while (sub_iterator.hasNext()) {
                Element sub_element = (Element) sub_iterator.next();
                System.out.println(sub_element.getName() + "="
                        + sub_element.getText());
            }
        }

        // 如访问一些特定的节点,可直接用XPath选择。
        List<Node> list = doc.selectNodes("//doc");
        System.out.println("doc节点数量:" + list.size());
        Node node = doc.selectSingleNode("//config/username");
        System.out.println(node.getName() + "=" + node.getText());

        System.out.println("----------------parseByDOM4J调用成功!----------------");
    }
    
    /**
     * Visitor方式调用实现遍历XML树。
     * 
     * @param filename
     * @throws Exception
     */
    public void printByVisitor(String filename) throws Exception {
        Document doc = getDocument(filename);
        Element root = doc.getRootElement();
        root.accept(new VisitorSupport() {
            @Override
            public void visit(Element element) {
                System.out.println(element.getName() + "=" + element.getText().trim());
            }

            @Override
            public void visit(Attribute attr) {
                System.out.println(attr.getName() + "=" + attr.getText());
            }
        });
        System.out.println("----------------printByVisitor调用成功!----------------");
    }

    /**
     * 传统方式,递归调用实现遍历XML树
     * 
     * @param filename
     * @throws Exception
     */
    public void printXML(String filename) throws Exception {
        Document doc = getDocument(filename);
        Element root = doc.getRootElement();

        walkTree(root);
        System.out.println("----------------printXML调用成功!----------------");
    }

    // 取得Document句柄
    private Document getDocument(String fileName) throws DocumentException {
        SAXReader reader = new SAXReader();
        Document document = reader.read(new File(fileName));
        return document;
    }

    // 遍历Element节点
    @SuppressWarnings("rawtypes")
    private void walkTree(Element element) throws Exception {
        // 先遍历属性值
        Iterator attr_iterator = element.attributeIterator();
        while (attr_iterator.hasNext()) {
            Attribute attr = (Attribute) attr_iterator.next();
            System.out.println(attr.getName() + "=" + attr.getText());
        }

        // 再遍历下面节点值
        for (int i = 0, size = element.nodeCount(); i < size; i++) {
            Node sub_node = element.node(i);
            if (sub_node instanceof Element) {
                Element sub_element = (Element) sub_node;
                System.out.println(sub_element.getName() + "="
                        + sub_element.getText().trim());

                walkTree((Element) sub_node); // 递归
            }
        }
    }

    public static void main(String[] args) throws Exception {
        DOM4JTest ins = new DOM4JTest();
        ins.writeXMLFile("bbs.xml"); // 先调用此方法,以生成测试XML文件
        ins.parseByDOM4J("bbs.xml");
        ins.printXML("bbs.xml");
        ins.printByVisitor("bbs.xml");
    }
}
原文地址:https://www.cnblogs.com/nayitian/p/2869283.html