手记

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

1.定义Book类

package com.imooc.book;

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、定义DOM类

package com.imooc.dom;

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

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.imooc.book.Book;

/**
 * 以DOM方式解析books.xml文件
 * 
 * @author Administrator
 *
 */
public class DOM {

    // 用于存储解析的书
    private List<Book> bookStore = new ArrayList<Book>();

    // 获得解析的每一书
    public List<Book> getBookStore() {
        return bookStore;
    }

    public void dom() {

        // 创建Book对象
        Book oneBook = null;

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

        try {

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

            // 创建Document对象
            Document document = db.parse("src/res/books.xml");

            // book节点的集合
            NodeList nodeList = document.getElementsByTagName("book");

            // 遍历每一个book节点
            for (int i = 0; i < nodeList.getLength(); i++) {

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

                // 每个book节点属性集合
                NamedNodeMap attrs = nodeList.item(i).getAttributes();

                // 遍历每个book节点属性
                for (int j = 0; j < attrs.getLength(); j++) {

                    // 设置对象oneBook的id属性
                    if (attrs.item(j).getNodeName().equals("id")) {
                        oneBook.setId(Integer.parseInt(attrs.item(j).getNodeValue()));
                    }
                }

                // 获取每个book节点的集合
                NodeList nodes = nodeList.item(i).getChildNodes();

                // 遍历每个book节点的子节点
                for (int k = 0; k < nodes.getLength(); k++) {

                    switch (nodes.item(k).getNodeName()) {

                    case "name":
                        oneBook.setName(nodes.item(k).getTextContent());
                        break;

                    case "author":
                        oneBook.setAuthor(nodes.item(k).getTextContent());
                        break;

                    case "year":
                        oneBook.setYear(Integer.parseInt(nodes.item(k).getTextContent()));
                        break;

                    case "price":
                        oneBook.setPrice(Double.parseDouble(nodes.item(k).getTextContent()));
                        break;

                    case "language":
                        oneBook.setLanguage(nodes.item(k).getTextContent());
                        break;

                    default:
                        break;
                    }
                }
                // 对象bookStroe添加一本书
                bookStore.add(oneBook);

                // 清空oneBook对象
                oneBook = null;
            }

        } catch (ParserConfigurationException e) {

            e.printStackTrace();

        } catch (SAXException e) {

            e.printStackTrace();

        } catch (IOException e) {

            e.printStackTrace();

        }
    }
}

3.1、创建一个Handler类,继承DefaultHandler类

package com.imooc.sax;

import java.util.ArrayList;
import java.util.List;

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

import com.imooc.book.Book;

public class Handler extends DefaultHandler {

    // 用于存储解析的所有书
    private List<Book> bookStore = new ArrayList<Book>();

    // 用于存储解析的一本书
    Book oneBook = null;

    // 用于存储每个元素的内容
    String textContent = null;

    // 获得解析的每一书
    public List<Book> getBookStore() {
        return bookStore;
    }

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

        if (qName.equals("book")) {
            // 初始化oneBook对象
            oneBook = new Book();

            // 遍历每一个Book元素的属性
            for (int i = 0; i < attributes.getLength(); i++) {
                // 设置oneBook对象的id
                if (attributes.getQName(i).equals("id"))
                    oneBook.setId(Integer.parseInt(attributes.getValue(i)));
            }
        }

    }

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

        // 每个元素的文本内容
        textContent = new String(ch, start, length);
    }

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

        switch (qName) {

        case "name":
            oneBook.setName(textContent);
            break;

        case "author":
            oneBook.setAuthor(textContent);
            break;

        case "year":
            oneBook.setYear(Integer.parseInt(textContent));
            break;

        case "price":
            oneBook.setPrice(Double.parseDouble(textContent));
            break;

        case "language":
            oneBook.setLanguage(textContent);
            break;

        default:
            break;
        }

        if (qName.equals("book")) {

            // 添加一本书
            this.bookStore.add(oneBook);

            // 清空oneBook变量
            oneBook = null;
        }
    }

}

3.2、定义SAX类

package com.imooc.sax;

import java.io.IOException;
import java.util.List;

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方式解析books.xml文件
 * 
 * @author Administrator
 *
 */
public class SAX {

    public List<Book> sax() {

        // 创建SAXParserFactory对象
        SAXParserFactory spf = SAXParserFactory.newInstance();

        //声明Handler对象
        Handler handler = null;

        try {

            // 创建SAXParser对象
            SAXParser sp = spf.newSAXParser();

            // 初始化Handler对象handler
            handler = new Handler();

            // 解析books.xml
            sp.parse("src/res/books.xml", handler);

        } catch (ParserConfigurationException e) {

            e.printStackTrace();

        } catch (SAXException e) {

            e.printStackTrace();

        } catch (IOException e) {

            e.printStackTrace();

        }

        //返回解析的结果
        return handler.getBookStore();
    }
}

4、定义JDOM类

package com.imooc.jdom;

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

import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;

import com.imooc.book.Book;

/**
 * 以JDOM方式解析books.xml文件
 * 
 * @author Administrator
 *
 */
public class JDOM {

    // 用于存储解析的所有书
    private List<Book> bookStore = new ArrayList<Book>();

    // 获得解析的每一书
    public List<Book> getBookStore() {
        return bookStore;
    }

    public void jdom() {

        // 创建SAXBuilder对象
        SAXBuilder saxBuilder = new SAXBuilder();

        // 声明Document对象
        Document document = null;

        try {

            // 初始化document对象
            document = saxBuilder.build(new File("src/res/books.xml"));

            // 获得根节点
            Element rootNode = document.getRootElement();

            // 获得book元素集合
            List<Element> books = rootNode.getChildren("book");

            // 遍历每一个book元素
            for (Element book : books) {

                // 创建一个Book对象
                Book oneBook = new Book();

                // 获得每一个book元素的属性集合
                List<Attribute> attrs = book.getAttributes();
                for (Attribute attr : attrs) {
                    if (attr.getName().equals("id"))
                        oneBook.setId(Integer.parseInt(attr.getValue()));
                }

                // 获得每一个书的元素集合
                List<Element> elements = book.getChildren();

                // 遍历每一本书的每一个元素
                for (Element element : elements) {
                    switch (element.getName()) {

                    case "name":
                        oneBook.setName(element.getText());
                        break;

                    case "author":
                        oneBook.setAuthor(element.getText());
                        break;

                    case "year":
                        oneBook.setYear(Integer.parseInt(element.getText()));
                        break;

                    case "price":
                        oneBook.setPrice(Double.parseDouble(element.getText()));
                        break;

                    case "language":
                        oneBook.setLanguage(element.getText());
                        break;

                    default:
                        break;
                    }
                }

                // 存储一本书
                bookStore.add(oneBook);

                // 清空变量oneBook
                oneBook = null;
            }

        } catch (JDOMException e) {

            e.printStackTrace();

        } catch (IOException e) {

            e.printStackTrace();

        }
    }

}

5、定义DOM4J类

package com.imooc.dom4j;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.imooc.book.Book;

/**
 * 以DOM4J方式解析books.xml文件
 * 
 * @author Administrator
 *
 */
public class DOM4J {

    // 用于存储解析的所有书
    private List<Book> bookStore = new ArrayList<Book>();

    // 获得解析的每一书
    public List<Book> getBookStore() {
        return bookStore;
    }

    public void dom4j() {

        // 创建一个SAXReader对象
        SAXReader saxReader = new SAXReader();

        try {

            // 创建一个Document对象
            Document document = saxReader.read(new File("src/res/books.xml"));

            // 获得根节点
            Element rootNode = document.getRootElement();

            // 获得book元素的集合
            @SuppressWarnings("unchecked")
            List<Element> books = rootNode.elements("book");

            // 遍历每一个book元素
            for (Element book : books) {
                // 创建一本书
                Book oneBook = new Book();

                // 获得每一个book元素的属性集合
                @SuppressWarnings("unchecked")
                List<Attribute> attrs = book.attributes();

                // 遍历每一个book元素的属性
                for (Attribute attr : attrs) {

                    // 设置oneBook的id属性
                    if (attr.getName().equals("id"))
                        oneBook.setId(Integer.parseInt(attr.getValue()));
                }

                // 获得每一个book元素的子元素的迭代器
                @SuppressWarnings("unchecked")
                Iterator<Element> elements = book.elementIterator();

                // 遍历迭代器
                while (elements.hasNext()) {
                    // 获得每一个book元素下的某个子元素
                    Element element = elements.next();

                    switch (element.getName()) {

                    case "name":
                        oneBook.setName(element.getText());
                        break;

                    case "author":
                        oneBook.setAuthor(element.getText());
                        break;

                    case "year":
                        oneBook.setYear(Integer.parseInt(element.getText()));
                        break;

                    case "price":
                        oneBook.setPrice(Double.parseDouble(element.getText()));
                        break;

                    case "language":
                        oneBook.setLanguage(element.getText());
                        break;

                    default:
                        break;
                    }

                }

                // 添加一本书
                this.bookStore.add(oneBook);

                // 清空变量oneBook
                oneBook = null;
            }

        } catch (DocumentException e) {

            e.printStackTrace();

        }

    }
}

6、定义测试类Test,使用JUint方法测试;

package com.imooc.test;

import com.imooc.dom.DOM;
import com.imooc.dom4j.DOM4J;
import com.imooc.jdom.JDOM;
import com.imooc.sax.SAX;

public class Test {
    @org.junit.Test
    public void testParser() {

        /*
         * 解析books.xml(9807KB)文件里的40多万本书,性能SAX > DOM4J > JDOM  > DOM
         * 数据量大时,建议使用SAX方式,数据量小时,建议使用DOM4J方式
         */
        long start = System.currentTimeMillis();
        new DOM().dom();
        System.out.println("DOM解析books.xml耗时: " + (System.currentTimeMillis() - start));

        start = System.currentTimeMillis();
        new SAX().sax();
        System.out.println("SAX解析books.xml耗时: " + (System.currentTimeMillis() - start));

        start = System.currentTimeMillis();
        new JDOM().jdom();
        System.out.println("JDOM解析books.xml耗时: " + (System.currentTimeMillis() - start));

        start = System.currentTimeMillis();
        new DOM4J().dom4j();
        System.out.println("DOM4J解析books.xml耗时: " + (System.currentTimeMillis() - start));

    }
}
6人推荐
随时随地看视频
慕课网APP