为了账号安全,请及时绑定邮箱和手机立即绑定

DOM、SAX、JDOM和DOM4J四种方式生成XML文件性能对比

标签:
Java

1、定义Book类

package com.imooc.book;

/**
 * 存储从XML文档读取到的某个book元素的内容
 * 
 * @author Administrator
 *
 */
public class Book {
    // 书的id
    private int id;

    // 书名
    private String name;

    // 书的作者
    private String author;

    // 书的出版年份
    private int year;

    // 书的售价
    private double price;

    // 书的语言
    private String language;

    // 无参构造方法
    public Book() {
        super();
    }

    // 有参构造方法
    public Book(int id, String name, String author, int year, double price, String language) {
        super();
        this.id = id;
        this.name = name;
        this.author = author;
        this.year = year;
        this.price = price;
        this.language = language;
    }

    // 覆写toString()方法,显示书的属性信息
    @Override
    public String toString() {
        return "Book [id=" + id + ", name=" + name + ", author=" + author + ", year=" + year + ", price=" + price
                + ", language=" + language + "]";
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public String getLanguage() {
        return language;
    }

    public void setLanguage(String language) {
        this.language = language;
    }

}

2、使用SAX方式解析XML文档,并存储在ArrayList对象中
2.1、定义Handler类

package com.imooc.parse;

import java.util.ArrayList;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import com.imooc.book.Book;

/**
 * Handler类继承DefaultHandler类,并覆写startElement、endElement和characters方法
 * 
 * @author Administrator
 *
 */

public class Handler extends DefaultHandler {

    // 存储读到的书籍
    private ArrayList<Book> books = new ArrayList<Book>();

    // 元素内容
    String textContent = null;

    // 声明一个Book对象
    Book book = null;

    // 获得书籍
    public ArrayList<Book> getBooks() {
        return books;
    }

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        super.startElement(uri, localName, qName, attributes);

        // book元素
        if (qName.equals("book")) {

            // 初始化book对象
            book = new Book();

            // 设置book元素的属性
            for (int i = 0; i < attributes.getLength(); i++) {
                if (attributes.getQName(i).equals("id"))
                    book.setId(Integer.parseInt(attributes.getValue(i)));
            }
        }

    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        super.endElement(uri, localName, qName);
        // book元素
        if (qName.equals("book")) {

            // 添加解析的一本书
            this.books.add(book);

            // 清空变量
            book = null;
        }

        // 设置书的属性
        switch (qName) {
        case "name":
            this.book.setName(textContent);
            break;
        case "author":
            this.book.setAuthor(textContent);
            break;
        case "year":
            this.book.setYear(Integer.parseInt(textContent));
            break;
        case "price":
            this.book.setPrice(Double.parseDouble(textContent));
            break;
        case "language":
            this.book.setLanguage(textContent);
            break;
        default:
            break;
        }

    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        super.characters(ch, start, length);

        // 获得文本的内容
        this.textContent = new String(ch, start, length);

    }

}

2.2定义SAX类,用于解析XML文档

package com.imooc.parse;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.SAXException;

import com.imooc.book.Book;

/**
 * 以SAX方式解析XML文档
 * 
 * @author Administrator
 *
 */
public class SAX {

    /**
     * 
     * @param path
     *            XML文档路径
     * @return 解析XML文档,并存储在ArrayList列表中
     */
    public static ArrayList<Book> parseXML(String path) {

        // 创建 一个SAXParserFactory对象
        SAXParserFactory factory = SAXParserFactory.newInstance();

        // 声明一个SAXParser对象
        SAXParser parser;

        // 创建一个Handler对象
        Handler handler = new Handler();

        try {

            // 初始化SAXParser对象
            parser = factory.newSAXParser();

            // 解析XML文档
            parser.parse(new File(path), handler);

        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 返回读取到的书籍
        return handler.getBooks();
    }
}

3、定义DOM类,使用DOM方式(将ArrayList对象的属性)生成XML文档

package com.imooc.dom;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import com.imooc.book.Book;

/**
 * 以DOM方式生成XML文档 
 * 流程: 
 * 1.创建DocumentBuilderFactory对象
 * 2.创建DocumentBuilder对象
 * 3.创建Document对象
 * 4.设置对象document的声明standalone
 * 5.创建元素
 * 6.创建TransformerFactory对象
 * 7.创建Transformer对象
 * 8.设置XML文档的格式
 * 9.使用transform方法以字节流写XML文档
 * @author Administrator
 *
 */

public class DOM {

    /**
     * 
     * @param books
     *            XML文档的内容
     * @param path
     *            生成的XML文档路径
     */
    public static void genXML(ArrayList<Book> books, String path) {

        // 创建一个DocumentBuilderFactory对象
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

        try {

            // 创建一个DocumentBuilder对象
            DocumentBuilder db = dbf.newDocumentBuilder();

            // 创建一个Document对象
            Document document = db.newDocument();

            // 设置standAlone
            document.setXmlStandalone(true);

            // 创建根节点
            Element bookStore = document.createElement("bookstore");

            // 遍历书籍books
            for (Book oneBook : books) {

                // 创建book元素
                Element book = document.createElement("book");

                // 将元素book添加到元素bookstore下
                bookStore.appendChild(book);

                // name元素
                if (oneBook.getName() != null && !oneBook.getName().trim().equals("")) {
                    // 创建name元素
                    Element name = document.createElement("name");

                    // 设置name元素的文本内容
                    name.setTextContent(oneBook.getName());

                    // 添加name元素
                    book.appendChild(name);
                }

                // author元素
                if (oneBook.getAuthor() != null && !oneBook.getAuthor().trim().equals("")) {
                    // 创建author元素
                    Element author = document.createElement("author");

                    // 设置author元素的文本内容
                    author.setTextContent(oneBook.getAuthor());

                    // 添加author元素
                    book.appendChild(author);
                }

                // year元素
                if (Integer.toString(oneBook.getYear()) != null
                        && !Integer.toString(oneBook.getYear()).trim().equals("")) {
                    // 创建year元素
                    Element year = document.createElement("year");

                    // 设置year元素的文本内容
                    year.setTextContent(Integer.toString(oneBook.getYear()));

                    // 添加year元素
                    book.appendChild(year);
                }

                // price元素
                if (Double.toString(oneBook.getPrice()) != null
                        && !Double.toString(oneBook.getPrice()).trim().equals("")) {
                    // 创建price元素
                    Element price = document.createElement("price");

                    // 设置price元素的文本内容
                    price.setTextContent(Double.toString(oneBook.getPrice()));

                    // 添加price元素
                    book.appendChild(price);
                }

                // language元素
                if (oneBook.getLanguage() != null && !oneBook.getLanguage().trim().equals("")) {
                    // 创建language元素
                    Element language = document.createElement("language");

                    // 设置language元素的文本内容
                    language.setTextContent(oneBook.getLanguage());

                    // 添加language元素
                    book.appendChild(language);
                }

            }

            // 将根节点加入到document中
            document.appendChild(bookStore);

            // 创建一个TransformerFactory对象
            TransformerFactory tff = TransformerFactory.newInstance();

            // 创建一个Transformer对象
            Transformer transformer = tff.newTransformer();

            // 设置XML文件“换行”
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");

            // 设置XML文档的编码
            transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");

            // 创建一个文件对象file
            File file = new File(path);

            // 如果上级目录不存在,则创建上级目录
            if (!file.getParentFile().exists())
                file.getParentFile().mkdirs();

            // 如果文件不存在,则创建文件
            if (!file.exists())
                file.createNewFile();

            // document内容写通过输出流XML文档
            transformer.transform(new DOMSource(document), new StreamResult(file));

        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (TransformerConfigurationException e) {
            e.printStackTrace();
        } catch (TransformerException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

4、定义SAX类,使用SAX方式生成XML文档

package com.imooc.sax;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;

import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;

import com.imooc.book.Book;

/**
 * 以SAX方式生成XML文档
 * 流程:
 * 1.创建SAXTransformerFactory对象
 * 2.创建TransformerHandler对象
 * 3.创建Transformer对象,用于设置XML文档的格式
 * 4.添加元素,属性和文本内容
 * 注意:元素的属性由类AttributesImpl对象设置
 * @author Administrator
 *
 */
public class SAX {
    /**
     * 
     * @param books
     *            XML文档的内容
     * @param path
     *            生成的XML文档路径
     */
    public static void genXML(ArrayList<Book> books, String path) {

        // 创建一个SAXTransformerFactory对象
        SAXTransformerFactory factory = (SAXTransformerFactory) SAXTransformerFactory.newInstance();

        try {

            // 创建一个TransformerHandler对象
            TransformerHandler handler = factory.newTransformerHandler();

            // 创建一个Transformer对象
            Transformer format = handler.getTransformer();

            // 设置XML文档“换行”
            format.setOutputProperty(OutputKeys.INDENT, "yes");

            // 设置XML文档的编码
            format.setOutputProperty(OutputKeys.ENCODING, "UTF-8");

            // 创建一个文件对象file
            File file = new File(path);

            // 如果上级目录不存在,则创建上级目录
            if (!file.getParentFile().exists())
                file.getParentFile().mkdirs();

            // 如果文件不存在,则创建文件
            if (!file.exists())
                file.createNewFile();

            // 以字节流形式写XML文档
            handler.setResult(new StreamResult(file));

            // 创建一个AttributesImpl对象
            AttributesImpl atts = new AttributesImpl();

            // XML文档开始
            handler.startDocument();

            // 根节点开始标签
            handler.startElement("", "", "bookstore", atts);

            // 遍历
            for (Book oneBook : books) {

                // 清空属性
                atts.clear();

                // 添加book标签的属性
                if (Integer.toString(oneBook.getId()) != null && !Integer.toString(oneBook.getId()).trim().equals(""))
                    atts.addAttribute("", "", "id", "", Integer.toString(oneBook.getId()));

                // book元素开始标签
                handler.startElement("", "", "book", atts);

                // name元素
                if (oneBook.getName() != null && !oneBook.getName().trim().equals("")) {
                    // 清空属性
                    atts.clear();

                    // name元素开始标签
                    handler.startElement("", "", "name", atts);

                    // 设置name元素的文本内容
                    handler.characters(new String(oneBook.getName()).toCharArray(), 0, oneBook.getName().length());

                    // name元素结束标签
                    handler.endElement("", "", "name");
                }

                // author元素
                if (oneBook.getAuthor() != null && !oneBook.getAuthor().trim().equals("")) {
                    // 清空属性
                    atts.clear();

                    // author元素开始标签
                    handler.startElement("", "", "author", atts);

                    // 设置author元素的文本内容
                    handler.characters(new String(oneBook.getAuthor()).toCharArray(), 0, oneBook.getAuthor().length());

                    // author元素结束标签
                    handler.endElement("", "", "author");
                }

                // year元素
                if (Integer.toString(oneBook.getYear()) != null
                        && !Integer.toString(oneBook.getYear()).trim().equals("")) {
                    // 清空属性
                    atts.clear();

                    // year元素开始标签
                    handler.startElement("", "", "year", atts);

                    // 设置year元素的文本内容
                    handler.characters(new String(Integer.toString(oneBook.getYear())).toCharArray(), 0,
                            Integer.toString(oneBook.getYear()).length());

                    // year元素结束标签
                    handler.endElement("", "", "year");
                }

                // price元素
                if (Double.toString(oneBook.getPrice()) != null
                        && !Double.toString(oneBook.getPrice()).trim().equals("")) {
                    // 清空属性
                    atts.clear();

                    // price元素开始标签
                    handler.startElement("", "", "price", atts);

                    // 设置price元素的文本内容
                    handler.characters(new String(Double.toString(oneBook.getPrice())).toCharArray(), 0,
                            Double.toString(oneBook.getPrice()).length());

                    // price元素结束标签
                    handler.endElement("", "", "price");
                }

                // language元素
                if (oneBook.getLanguage() != null && !oneBook.getLanguage().trim().equals("")) {
                    // 清空属性
                    atts.clear();

                    // language元素开始标签
                    handler.startElement("", "", "language", atts);

                    // 设置language元素的文本内容
                    handler.characters(new String(oneBook.getLanguage()).toCharArray(), 0,
                            oneBook.getLanguage().length());

                    // language元素结束标签
                    handler.endElement("", "", "language");
                }

                // book元素结束标签
                handler.endElement("", "", "book");
            }

            // 根节点结束标签
            handler.endElement("", "", "bookstore");

            // XML文档结束
            handler.endDocument();

        } catch (TransformerConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

5、定义JDOM类,使用JDOM方式生成XML文档

package com.imooc.jdom;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;

import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;

import com.imooc.book.Book;

/**
 * 以JDOM方式生成XML文档
 * 流程:
 * 1.将元素添加到Document对象中
 * 2.通过Format的getPrettyFormat()方法创建一个Format对象,用于设置XML文档的格式
 * 3.创建一个XMLOutputter对象,关联Format对象
 * 4.使用类XMLOutputter中的output方法写XML文档
 * @author Administrator
 *
 */
public class JDOM {

    /**
     * 
     * @param books
     *            XML文档的内容
     * @param path
     *            生成的XML文档路径
     */
    public static void genXML(ArrayList<Book> books, String path) {

        // 创建bookstore元素
        Element bookStore = new Element("bookstore");

        // 遍历
        for (Book oneBook : books) {
            // 创建book元素
            Element book = new Element("book");

            // book标签的属性
            if (Integer.toString(oneBook.getId()) != null && !Integer.toString(oneBook.getId()).trim().equals(""))
                // 设置book标签的属性
                book.setAttribute("id", Integer.toString(oneBook.getId()));

            // name元素
            if (oneBook.getName() != null && !oneBook.getName().trim().equals("")) {
                // 创建name元素
                Element name = new Element("name");

                // 设置name元素的内容
                name.setText(oneBook.getName());

                // 将name元素添加到book元素下
                book.addContent(name);
            }

            // author元素
            if (oneBook.getAuthor() != null && !oneBook.getAuthor().trim().equals("")) {
                // 创建author元素
                Element author = new Element("author");

                // 设置author元素的内容
                author.setText(oneBook.getAuthor());

                // 将author元素添加到book元素下
                book.addContent(author);
            }

            // year元素
            if (Integer.toString(oneBook.getYear()) != null && !Integer.toString(oneBook.getYear()).trim().equals("")) {
                // 创建year元素
                Element year = new Element("year");

                // 设置year元素的内容
                year.setText(Integer.toString(oneBook.getYear()));

                // 将year元素添加到book元素下
                book.addContent(year);
            }

            // price元素
            if (Double.toString(oneBook.getPrice()) != null && !Double.toString(oneBook.getPrice()).trim().equals("")) {
                // 创建price元素
                Element price = new Element("price");

                // 设置price元素的内容
                price.setText(Double.toString(oneBook.getPrice()));

                // 将price元素添加到book元素下
                book.addContent(price);
            }

            // language元素
            if (oneBook.getLanguage() != null && !oneBook.getLanguage().trim().equals("")) {
                // 创建language元素
                Element language = new Element("language");

                // 设置language元素的内容
                language.setText(oneBook.getLanguage());

                // 将language元素添加到book元素下
                book.addContent(language);
            }

            // 将book元素添加到bookstore元素下
            bookStore.addContent(book);
        }

        // 创建一个Document对象
        Document document = new Document(bookStore);

        // 创建一个Format对象
        Format format = Format.getPrettyFormat();

        // 设置XML文档编码
        format.setEncoding("UTF-8");

        // 设置XML文档“换行”
        format.setIndent("");

        // 创建一个XMLOutputter对象
        XMLOutputter out = new XMLOutputter(format);

        try {
            // 创建一个文件对象file
            File file = new File(path);

            // 如果上级目录不存在,则创建上级目录
            if (!file.getParentFile().exists())
                file.getParentFile().mkdirs();

            // 如果文件不存在,则创建文件
            if (!file.exists())
                file.createNewFile();

            // 以字节流写XML文档
            out.output(document, new FileOutputStream(file));

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    public static void main(String[] args) {
        JDOM.genXML(com.imooc.parse.SAX.parseXML("src/res/books.xml"), "src/res/jdom.xml");
    }

}

6、定义DOM4J类,使用DOM4J方式生成XML文档

package com.imooc.dom4j;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

import com.imooc.book.Book;

/**
 * 以DOM4J方式生成XML文档
 * 流程:
 * 1.通过DocumentHelper类的createDocument()方法创建一个Document对象
 * 2.添加元素
 * 3.通过OutputFormat的createPrettyPrint()方法创建一个OutputFormat对象,用于设置XML文档的输出格式
 * 4.使用文件输出流和OutputFormat对象,创建一个XMLWriter对象
 * 5.XMLWriter对象write方法,将对象document的内容写入XML文档
 * 6.关闭资源
 * @author Administrator
 *
 */
public class DOM4J {

    /**
     * 
     * @param books
     *            XML文档的内容
     * @param path
     *            生成的XML文档路径
     */
    public static void genXML(ArrayList<Book> books, String path) {

        // 使用DocumentHelper类创建一个Document对象
        Document document = DocumentHelper.createDocument();

        // 添加根节点bookstore
        Element bookStore = document.addElement("bookstore");

        try {

            for (Book oneBook : books) {
                // 创建book元素
                Element book = bookStore.addElement("book");

                // book标签的属性
                if (Integer.toString(oneBook.getId()) != null && !Integer.toString(oneBook.getId()).trim().equals("")) {

                    // 为book元素添加属性
                    book.addAttribute("id", Integer.toString(oneBook.getId()));

                }

                // name元素
                if (oneBook.getName() != null && !oneBook.getName().trim().equals("")) {

                    // 创建name元素
                    Element name = book.addElement("name");

                    // 设置name元素的文本内容
                    name.setText(oneBook.getName());

                }

            }

            // 创建一个文件对象file
            File file = new File(path);

            // 如果上级目录不存在,则创建上级目录
            if (!file.getParentFile().exists())
                file.getParentFile().mkdirs();

            // 如果文件不存在,则创建文件
            if (!file.exists())
                file.createNewFile();

            // 创建字节输出流FileOutputStream对象
            FileOutputStream out = new FileOutputStream(file);

            // 创建一个OutputFormat对象(XML以比较友好的格式输出)
            OutputFormat format = OutputFormat.createPrettyPrint();

            // 设置XML文档编码
            format.setEncoding("UTF-8");

            // 设置XML文档缩进
            format.setIndent(true);

            // 创建一个XMLWriter对象
            XMLWriter writer = new XMLWriter(out, format);

            // 将内容写入XML文档
            writer.write(document);

            // 释放资源
            writer.close();

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

7、定义Test类,使用JUint方法测试DOM、SAX、JDOM和DOM4J的性能

package com.imooc.test;

import java.util.ArrayList;

import com.imooc.book.Book;
import com.imooc.dom.DOM;

public class Test {
    /*
     * 使用JUint4测试DOM、SAX、JDOM和DOM4J生成XML文档的性能 经测试;
     * 性能DOM4J > JDOM > DOM > SAX
     * 数据量大时,建议使用DOM4J方式,数据量小时,建议使用SAX方式;
     * 如果要频繁增、删和改元素,建议使用DOM方式。
     */
    @org.junit.Test
    public void test() {
        // 通过SAX方法获得XML文档的内容,并存储在ArrayList对象中
        ArrayList<Book> books = com.imooc.parse.SAX.parseXML("src\\res\\books.xml");

        // DOM
        // 开始时间
        Long start = System.currentTimeMillis();

        // 使用DOM方式写XML文档
        DOM.genXML(books, "src\\res\\dom.xml");

        // 结束时间
        Long end = System.currentTimeMillis();

        // DOM耗时
        System.out.println("DOM用时:" + (end - start) + "ms.");

        // SAX
        // 开始时间
        start = System.currentTimeMillis();

        // 使用SAX方式写XML文档
        DOM.genXML(books, "src\\res\\sax.xml");

        // 结束时间
        end = System.currentTimeMillis();

        // SAX耗时
        System.out.println("SAX用时:" + (end - start) + "ms.");

        // JDOM
        // 开始时间
        start = System.currentTimeMillis();

        // 使用JDOM方式写XML文档
        DOM.genXML(books, "src\\res\\jdom.xml");

        // 结束时间
        end = System.currentTimeMillis();

        // JDOM耗时
        System.out.println("JDOM用时:" + (end - start) + "ms.");

        // DOM4J
        // 开始时间
        start = System.currentTimeMillis();

        // 使用DOM4J方式写XML文档
        DOM.genXML(books, "src\\res\\dom4j.xml");

        // 结束时间
        end = System.currentTimeMillis();

        // DOM4J耗时
        System.out.println("DOM4J用时:" + (end - start) + "ms.");

    }
}
点击查看更多内容
5人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消