Java数据解析之XML

文章大纲

一、XML解析介绍
二、Java中XML解析介绍
三、XML解析实战
四、项目源码下载

一、XML解析介绍

  最基础的XML解析方式有DOM和SAX,DOM和SAX是与平台无关的官方解析方式,是基于事件驱动的解析方式。

1. DOM解析图解

DOM解析是直接把xml文件放入内存中,如果节点太多的话,就要考虑性能问题了。

2. SAX解析图解

SAX解析是走到哪个位置,就调用不同方法进行解析。

二、Java中XML解析介绍

  Java中常见解析XML的方式有DOM、SAX、DOM4J、JDOM

1. 各大框架比较

DOM
优点:
(1)形成树结构,直观好理解,代码更容易编写
(2)解析过程中树结构保留在内存中,方便修改
缺点:
(1)当XML文件较大时,对内存消耗比较大,容易影响解析性能并造成内存溢出

SAX
优点:
(1)采用事件驱动模式,对内存消耗较小
(2)适用于只需要处理XML中数据
缺点:
(1)不易编码
(2)很难同时访问同一个XML中的多处不同数据

JDOM
优点:
(1)是基于树的处理xml的java api,把树加载到内存中
(2)速度快
缺点:
(1)不能处理大于内存的文档
(2)不支持于DOM中相应遍历包

DOM4J
优点:
  dom4j有更复杂的api,所以dom4j比jdom有更大的灵活性

三、XML解析实战

1. 测试的XML文件:books.xml



 
   
    冰与火之歌  
    2014  
    89 
    
   
    安徒生童话  
    2004  
    77  
    English 
   

2. 通用实体类Book.java

package testall;

public class Book {
    private String id;
    private String name;
    private String author;
    private String year;
    private String price;
    private String language;
    public String getId() {
        return id;
    }
    public void setId(String 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 String getYear() {
        return year;
    }
    public void setYear(String year) {
        this.year = year;
    }
    public String getPrice() {
        return price;
    }
    public void setPrice(String price) {
        this.price = price;
    }
    public String getLanguage() {
        return language;
    }
    public void setLanguage(String language) {
        this.language = language;
    }
    
    
}

3. DOM实战

package dom;

import java.io.IOException;

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

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

/**
 * 应用 DOM 方式解析 XML
 * 
 * 在 Java 程序中通过自带的 DOM 方式解析 XML 文件,解析的内容包括属性名、属性值、节点名以及节点值
 * 
 * @author Administrator
 *
 */
public class DOMTest {

    public static void main(String[] args) {
        
        //创建一个DocumentBuilderFactory的对象
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        
        //创建一个DocumentBuilder的对象
        try {
            
            //创建DocumentBuilder对象
            DocumentBuilder db = dbf.newDocumentBuilder();
            
            //通过DocumentBuilder对象的parser方法加载books.xml文件到当前项目下
            Document document = db.parse("books.xml");
            
            //获取所有book节点的集合
            NodeList bookList = document.getElementsByTagName("book");
            
            //通过nodelist的getLength()方法可以获取bookList的长度
            System.out.println("一共有" + bookList.getLength() + "本书");
            
            //遍历每一个book节点
            for (int i = 0; i < bookList.getLength(); i++) {
                
                System.out.println("=================下面开始遍历第" + (i + 1) + "本书的内容=================");
                
                //通过 item(i)方法 获取一个book节点,nodelist的索引值从0开始
                Node book = bookList.item(i);
                
//              获取book节点的所有属性集合
                NamedNodeMap attrs = book.getAttributes();
                
                System.out.println("第 " + (i + 1) + "本书共有" + attrs.getLength() + "个属性");
                
//              遍历book的属性
                for (int j = 0; j < attrs.getLength(); j++) {
                    
                    //通过item(index)方法获取book节点的某一个属性
                    Node attr = attrs.item(j);
                    
                    //获取属性名
                    System.out.print("属性名:" + attr.getNodeName());
                    
                    //获取属性值
                    System.out.println("--属性值" + attr.getNodeValue());
                    
                }
                
//              //前提:已经知道book节点有且只能有1个id属性
//              //将book节点进行强制类型转换,转换成Element类型
//              Element book = (Element) bookList.item(i);
//              //通过getAttribute("id")方法获取属性值
//              String attrValue = book.getAttribute("id");
//              System.out.println("id属性的属性值为" + attrValue);
                //解析book节点的子节点
                NodeList childNodes = book.getChildNodes();
                
                //遍历childNodes获取每个节点的节点名和节点值
                System.out.println("第" + (i+1) + "本书共有" + 
                childNodes.getLength() + "个子节点");
                
                for (int k = 0; k < childNodes.getLength(); k++) {
                    
                    //区分出text类型的node以及element类型的node
                    if (childNodes.item(k).getNodeType() == Node.ELEMENT_NODE) {
                        
                        //获取了element类型节点的节点名
                        System.out.print("第" + (k + 1) + "个节点的节点名:" 
                                
                        + childNodes.item(k).getNodeName());
                        
//                      获取了element类型节点的节点值
                        
                        System.out.println("--节点值是:" + childNodes.item(k).getFirstChild().getNodeValue());
                        
//                      System.out.println("--节点值是:" + childNodes.item(k).getTextContent());
                        
                    }
                    
                }
                
                System.out.println("======================结束遍历第" + (i + 1) + "本书的内容=================");
            }
        } catch (ParserConfigurationException e) {
            
            e.printStackTrace();
            
        }  catch (SAXException e) {
            
            e.printStackTrace();
            
        } catch (IOException e) {
            
            e.printStackTrace();
        }
        
    }
}

运行结果如下图所示:

一共有2本书
=================下面开始遍历第1本书的内容=================
第 1本书共有1个属性
属性名:id--属性值1
第1本书共有7个子节点
第2个节点的节点名:name--节点值是:冰与火之歌
第4个节点的节点名:year--节点值是:2014
第6个节点的节点名:price--节点值是:89
======================结束遍历第1本书的内容=================
=================下面开始遍历第2本书的内容=================
第 2本书共有1个属性
属性名:id--属性值2
第2本书共有9个子节点
第2个节点的节点名:name--节点值是:安徒生童话
第4个节点的节点名:year--节点值是:2004
第6个节点的节点名:price--节点值是:77
第8个节点的节点名:language--节点值是:English
======================结束遍历第2本书的内容=================

Process finished with exit code 0

4. SAX实战

解析器SAXParserHandler.java如下

package sax;

import java.util.ArrayList;

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


public class SAXParserHandler extends DefaultHandler {
    
    String value = null;
    
    Book book = null;
    
    private ArrayList bookList = new ArrayList();
    
    public ArrayList getBookList() {
        
        return bookList;
    }
    

    int bookIndex = 0;
    
    /** 
     * XML开始解析时调用 
     *  
     */   
    @Override
    public void startDocument() throws SAXException {
        
        // TODO Auto-generated method stub
        super.startDocument();
        
        System.out.println("SAX解析开始");
    }
    
       /** 
        * XML全部解析完毕时调用 
        *  
        */  
    @Override
    public void endDocument() throws SAXException {
        
        // TODO Auto-generated method stub
        super.endDocument();
        
        System.out.println("SAX解析结束");
        
    }
    
      /** 
     * 解析元素节点 
     */  
    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        
        //调用DefaultHandler类的startElement方法
        super.startElement(uri, localName, qName, attributes);
        
        if (qName.equals("book")) {
            
            bookIndex++;
            
            //创建一个book对象
            book = new Book();
            
            //开始解析book元素的属性
            System.out.println("======================开始遍历某一本书的内容=================");
            
//          //已知book元素下属性的名称,根据属性名称获取属性值
//          String value = attributes.getValue("id");
//          System.out.println("book的属性值是:" + value);
            //不知道book元素下属性的名称以及个数,如何获取属性名以及属性值
            int num = attributes.getLength();
            
            for(int i = 0; i < num; i++){
                
                System.out.print("book元素的第" + (i + 1) +  "个属性名是:"
                        
                        + attributes.getQName(i));
            
                System.out.println("---属性值是:" + attributes.getValue(i));
                
                if (attributes.getQName(i).equals("id")) {
                    
                    book.setId(attributes.getValue(i));
                    
                }
            }
        }
        else if (!qName.equals("name") && !qName.equals("bookstore")) {
            
            System.out.print("节点名是:" + qName + "---");
            
        }
    }
    
      /** 
        * 遇到结束标签时调用 
        */ 
    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        
        //调用DefaultHandler类的endElement方法
        super.endElement(uri, localName, qName);
        
        //判断是否针对一本书已经遍历结束
        if (qName.equals("book")) {
            
            bookList.add(book);
            
            book = null;
            
            System.out.println("======================结束遍历某一本书的内容=================");
        }
        else if (qName.equals("name")) {
            book.setName(value);
        }
        else if (qName.equals("author")) {
            book.setAuthor(value);
        }
        else if (qName.equals("year")) {
            book.setYear(value);
        }
        else if (qName.equals("price")) {
            book.setPrice(value);
        }
        else if (qName.equals("language")) {
            book.setLanguage(value);
        }
    }
    
       /** 
     * 获取节点的值 
     */  
    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        
        // TODO Auto-generated method stub
        super.characters(ch, start, length);
        
        value = new String(ch, start, length);
        
        if (!value.trim().equals("")) {
            
            System.out.println("节点值是:" + value);
            
        }
    }
}

解析类SAXTest.java

package sax;

import java.util.ArrayList;

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


public class SAXParserHandler extends DefaultHandler {
    
    String value = null;
    
    Book book = null;
    
    private ArrayList bookList = new ArrayList();
    
    public ArrayList getBookList() {
        
        return bookList;
    }
    

    int bookIndex = 0;
    
    /** 
     * XML开始解析时调用 
     *  
     */   
    @Override
    public void startDocument() throws SAXException {
        
        // TODO Auto-generated method stub
        super.startDocument();
        
        System.out.println("SAX解析开始");
    }
    
       /** 
        * XML全部解析完毕时调用 
        *  
        */  
    @Override
    public void endDocument() throws SAXException {
        
        // TODO Auto-generated method stub
        super.endDocument();
        
        System.out.println("SAX解析结束");
        
    }
    
      /** 
     * 解析元素节点 
     */  
    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        
        //调用DefaultHandler类的startElement方法
        super.startElement(uri, localName, qName, attributes);
        
        if (qName.equals("book")) {
            
            bookIndex++;
            
            //创建一个book对象
            book = new Book();
            
            //开始解析book元素的属性
            System.out.println("======================开始遍历某一本书的内容=================");
            
//          //已知book元素下属性的名称,根据属性名称获取属性值
//          String value = attributes.getValue("id");
//          System.out.println("book的属性值是:" + value);
            //不知道book元素下属性的名称以及个数,如何获取属性名以及属性值
            int num = attributes.getLength();
            
            for(int i = 0; i < num; i++){
                
                System.out.print("book元素的第" + (i + 1) +  "个属性名是:"
                        
                        + attributes.getQName(i));
            
                System.out.println("---属性值是:" + attributes.getValue(i));
                
                if (attributes.getQName(i).equals("id")) {
                    
                    book.setId(attributes.getValue(i));
                    
                }
            }
        }
        else if (!qName.equals("name") && !qName.equals("bookstore")) {
            
            System.out.print("节点名是:" + qName + "---");
            
        }
    }
    
      /** 
        * 遇到结束标签时调用 
        */ 
    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        
        //调用DefaultHandler类的endElement方法
        super.endElement(uri, localName, qName);
        
        //判断是否针对一本书已经遍历结束
        if (qName.equals("book")) {
            
            bookList.add(book);
            
            book = null;
            
            System.out.println("======================结束遍历某一本书的内容=================");
        }
        else if (qName.equals("name")) {
            book.setName(value);
        }
        else if (qName.equals("author")) {
            book.setAuthor(value);
        }
        else if (qName.equals("year")) {
            book.setYear(value);
        }
        else if (qName.equals("price")) {
            book.setPrice(value);
        }
        else if (qName.equals("language")) {
            book.setLanguage(value);
        }
    }
    
       /** 
     * 获取节点的值 
     */  
    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        
        // TODO Auto-generated method stub
        super.characters(ch, start, length);
        
        value = new String(ch, start, length);
        
        if (!value.trim().equals("")) {
            
            System.out.println("节点值是:" + value);
            
        }
    }
}

运行结果如下所示:

SAX解析开始
======================开始遍历某一本书的内容=================
book元素的第1个属性名是:id---属性值是:1
节点值是:冰与火之歌
节点名是:year---节点值是:2014
节点名是:price---节点值是:89
======================结束遍历某一本书的内容=================
======================开始遍历某一本书的内容=================
book元素的第1个属性名是:id---属性值是:2
节点值是:安徒生童话
节点名是:year---节点值是:2004
节点名是:price---节点值是:77
节点名是:language---节点值是:English
======================结束遍历某一本书的内容=================
SAX解析结束
~!~!~!共有2本书
1
冰与火之歌
null
2014
89
null
----finish----
2
安徒生童话
null
2004
77
English
----finish----

Process finished with exit code 0

5. DOM4J实战

package 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;

/**
 * DOM4J 及 JDOM 不是 JAVA 提供官方解析 XML 的方式,但都是优秀的解析方法,简单易用;本章介绍在 JAVA 程序中如何通过这两种方式解析 XML 文件
 * 
 * @author Administrator
 *
 */
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("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();
        }

    }

}

运行结果如下所示:

=====开始遍历某一本书=====
属性名:id--属性值:1
节点名:name--节点值:冰与火之歌
节点名:year--节点值:2014
节点名:price--节点值:89
=====结束遍历某一本书=====
=====开始遍历某一本书=====
属性名:id--属性值:2
节点名:name--节点值:安徒生童话
节点名:year--节点值:2004
节点名:price--节点值:77
节点名:language--节点值:English
=====结束遍历某一本书=====

Process finished with exit code 0

6. JDOM实战

package jdom;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
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;

/**
 * DOM4J 及 JDOM 不是 JAVA 提供官方解析 XML 的方式,但都是优秀的解析方法,简单易用;本章介绍在 JAVA 程序中如何通过这两种方式解析 XML 文件
 * 
 * @author Administrator
 *
 */
public class JDOMTest {
    
    private static ArrayList booksList = new ArrayList();
    /**
     * @param args
     */
    public static void main(String[] args) {
        
        // 进行对books.xml文件的JDOM解析
        // 准备工作
        // 1.创建一个SAXBuilder的对象
        SAXBuilder saxBuilder = new SAXBuilder();
        
        InputStream in;
        
        try {
            
            // 2.创建一个输入流,将xml文件加载到输入流中
            in = new FileInputStream("books.xml");
            
            InputStreamReader isr = new InputStreamReader(in, "UTF-8");
            
            // 3.通过saxBuilder的build方法,将输入流加载到saxBuilder中
            Document document = saxBuilder.build(isr);
            
            // 4.通过document对象获取xml文件的根节点
            Element rootElement = document.getRootElement();
            
            // 5.获取根节点下的子节点的List集合
            List bookList = rootElement.getChildren();
            
            // 继续进行解析
            for (Element book : bookList) {
                
                Book bookEntity = new Book();
                System.out.println("======开始解析第" + (bookList.indexOf(book) + 1)
                        + "书======");
                // 解析book的属性集合
                List attrList = book.getAttributes();
                // //知道节点下属性名称时,获取节点值
                // book.getAttributeValue("id");
                // 遍历attrList(针对不清楚book节点下属性的名字及数量)
                for (Attribute attr : attrList) {
                    // 获取属性名
                    String attrName = attr.getName();
                    // 获取属性值
                    String attrValue = attr.getValue();
                    System.out.println("属性名:" + attrName + "----属性值:"
                            + attrValue);
                    if (attrName.equals("id")) {
                        bookEntity.setId(attrValue);
                    }
                }
                // 对book节点的子节点的节点名以及节点值的遍历
                List bookChilds = book.getChildren();
                for (Element child : bookChilds) {
                    System.out.println("节点名:" + child.getName() + "----节点值:"
                            + child.getValue());
                    if (child.getName().equals("name")) {
                        bookEntity.setName(child.getValue());
                    }
                    else if (child.getName().equals("author")) {
                        bookEntity.setAuthor(child.getValue());
                    }
                    else if (child.getName().equals("year")) {
                        bookEntity.setYear(child.getValue());
                    }
                    else if (child.getName().equals("price")) {
                        bookEntity.setPrice(child.getValue());
                    }
                    else if (child.getName().equals("language")) {
                        bookEntity.setLanguage(child.getValue());
                    }
                }
                System.out.println("======结束解析第" + (bookList.indexOf(book) + 1)
                        + "书======");
                booksList.add(bookEntity);
                bookEntity = null;
                System.out.println(booksList.size());
                System.out.println(booksList.get(0).getId());
                System.out.println(booksList.get(0).getName());
                
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (JDOMException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

运行结果如下所示:

======开始解析第1书======
属性名:id----属性值:1
节点名:name----节点值:冰与火之歌
节点名:year----节点值:2014
节点名:price----节点值:89
======结束解析第1书======
1
1
冰与火之歌
======开始解析第2书======
属性名:id----属性值:2
节点名:name----节点值:安徒生童话
节点名:year----节点值:2004
节点名:price----节点值:77
节点名:language----节点值:English
======结束解析第2书======
2
1
冰与火之歌

Process finished with exit code 0

7. 四种解析方式性能测试

package testall;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

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

import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;
import org.jdom2.Attribute;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import dom4j.Book;
import sax.SAXParserHandler;

public class ParseTest {


    public static void domXmlParser() {
        ArrayList bookLists = new ArrayList();
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        try {
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document document = db.parse("books.xml");
            NodeList bookList = document.getElementsByTagName("book");
            for (int i = 0; i < bookList.getLength(); i++) {
                Node book = bookList.item(i);
                Book bookEntity = new Book();
                NamedNodeMap attrs = book.getAttributes();
                for (int j = 0; j < attrs.getLength(); j++) {
                    Node attr = attrs.item(j);
                    if (attr.getNodeName().equals("id")) {
                        bookEntity.setId(attr.getNodeValue());
                    }
                }
                NodeList childNodes = book.getChildNodes();
                for (int k = 0; k < childNodes.getLength(); k++) {
                    if (childNodes.item(k).getNodeType() == Node.ELEMENT_NODE) {
                        String name = childNodes.item(k).getNodeName();
                        String value = childNodes.item(k).getFirstChild().getNodeValue();
                        if (name.equals("name")) {
                            bookEntity.setName(value);
                        }
                        else if (name.equals("author")) {
                            bookEntity.setAuthor(value);
                        }
                        else if (name.equals("year")) {
                            bookEntity.setYear(value);
                        }
                        else if (name.equals("price")) {
                            bookEntity.setPrice(value);
                        }
                        else if (name.equals("language")) {
                            bookEntity.setLanguage(value);
                        }
                    }
                }
                bookLists.add(bookEntity);
                bookEntity = null;
            }
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    public static void saxXmlParser(){
        SAXParserFactory factory = SAXParserFactory.newInstance();
        try {
            SAXParser parser = factory.newSAXParser();
            SAXParserHandler handler = new SAXParserHandler();
            parser.parse("books.xml", handler);
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    public static void jdomXmlParser() {
        ArrayList booksList = new ArrayList();
        SAXBuilder saxBuilder = new SAXBuilder();
        InputStream in;
        try {
            in = new FileInputStream("books.xml");
            InputStreamReader isr = new InputStreamReader(in, "UTF-8");
            org.jdom2.Document document = saxBuilder.build(isr);
            org.jdom2.Element rootElement = document.getRootElement();
            List bookList = rootElement.getChildren();
            for (org.jdom2.Element book : bookList) {
                Book bookEntity = new Book();
                List attrList = book.getAttributes();
                for (Attribute attr : attrList) {
                    String attrName = attr.getName();
                    String attrValue = attr.getValue();
                    if (attrName.equals("id")) {
                        bookEntity.setId(attrValue);
                    }
                }
                List bookChilds = book.getChildren();
                for (org.jdom2.Element child : bookChilds) {
                    if (child.getName().equals("name")) {
                        bookEntity.setName(child.getValue());
                    }
                    else if (child.getName().equals("author")) {
                        bookEntity.setAuthor(child.getValue());
                    }
                    else if (child.getName().equals("year")) {
                        bookEntity.setYear(child.getValue());
                    }
                    else if (child.getName().equals("price")) {
                        bookEntity.setPrice(child.getValue());
                    }
                    else if (child.getName().equals("language")) {
                        bookEntity.setLanguage(child.getValue());
                    }
                }
                booksList.add(bookEntity);
                bookEntity = null;
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (JDOMException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    
    public static void dom4jXmlParser(){
        ArrayList booksList = new ArrayList();
        SAXReader reader = new SAXReader();
        try {
            org.dom4j.Document document = reader.read(new File("books.xml"));
            org.dom4j.Element bookStore = document.getRootElement();
            List bookEles = bookStore.elements();
            for (org.dom4j.Element book : bookEles) {
                Book bookEntity = new Book();
                List bookAttrs = book.attributes();
                for (org.dom4j.Attribute attr : bookAttrs) {
                    if (attr.getName().equals("id")) {
                        bookEntity.setId(attr.getValue());
                    }
                }
                List bookss = book.elements();
                for (org.dom4j.Element bookChild : bookss) {
                    String name = bookChild.getName();
                    String value = bookChild.getStringValue();
                    if (name.equals("name")) {
                        bookEntity.setName(value);
                    }
                    else if (name.equals("author")) {
                        bookEntity.setAuthor(value);
                    }
                    else if (name.equals("year")) {
                        bookEntity.setYear(value);
                    }
                    else if (name.equals("price")) {
                        bookEntity.setPrice(value);
                    }
                    else if (name.equals("language")) {
                        bookEntity.setLanguage(value);
                    }
                }
                booksList.add(bookEntity);
                bookEntity = null;
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        
        System.out.println("性能测试:");
        
        //测试DOM的性能:
        long start = System.currentTimeMillis();
        domXmlParser();
        System.out.println("DOM:"+ (System.currentTimeMillis() - start) );
        //测试SAX的性能:
        start = System.currentTimeMillis();
        saxXmlParser();
        System.out.println("SAX:"+ (System.currentTimeMillis() - start) );
        //测试JDOM的性能:
        start = System.currentTimeMillis();
        jdomXmlParser();
        System.out.println("JDOM:"+ (System.currentTimeMillis() - start) );
        //测试DOM4J的性能:
        start = System.currentTimeMillis();
        dom4jXmlParser();
        System.out.println("DOM4J:"+ (System.currentTimeMillis() - start) );
    
    }
}

运行结果如下所示:

性能测试:
DOM:78
SAX解析开始
======================开始遍历某一本书的内容=================
book元素的第1个属性名是:id---属性值是:1
节点值是:冰与火之歌
节点名是:year---节点值是:2014
节点名是:price---节点值是:89
======================结束遍历某一本书的内容=================
======================开始遍历某一本书的内容=================
book元素的第1个属性名是:id---属性值是:2
节点值是:安徒生童话
节点名是:year---节点值是:2004
节点名是:price---节点值是:77
节点名是:language---节点值是:English
======================结束遍历某一本书的内容=================
SAX解析结束
SAX:13
JDOM:88
DOM4J:82

Process finished with exit code 0

总结:
  JDOM 在性能测试时表现不佳,在测试 10M 文档时内存溢出。在小文档情况下还值得考虑使用 JDOM。dom4j不适合大文件的解析,因为它是一下子将文件加载到内存中,所以有可能出现内存溢出,sax是基于事件来对xml进行解析的,所以他可以解析大文件的xml,也正是因为如此,所以dom4j可以对xml进行灵活的增删改查和导航,而sax没有这么强的灵活性,所以sax经常是用来解析大型xml文件,而要对xml文件进行一些灵活(crud)操作就用dom4j。

四、项目源码下载

链接:https://pan.baidu.com/s/1vi54ujtSVai17SFzu706Ew
密码:py54

你可能感兴趣的:(Java数据解析之XML)