欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java数据解析之XML

程序员文章站 2022-04-08 17:25:40
文章大纲 一、XML解析介绍二、Java中XML解析介绍三、XML解析实战四、项目源码下载 一、XML解析介绍 最基础的XML解析方式有DOM和SAX,DOM和SAX是与平台无关的官方解析方式,是基于事件驱动的解析方式。 1. DOM解析图解 DOM解析是直接把xml文件放入内存中,如果节点太多的话 ......

文章大纲

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

 
Java数据解析之XML

一、xml解析介绍

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

1. dom解析图解

 
Java数据解析之XML

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

2. sax解析图解

 
Java数据解析之XML

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

<?xml version="1.0" encoding="utf8"?>

<bookstore> 
  <book id="1"> 
    <name>冰与火之歌</name>  
    <year>2014</year>  
    <price>89</price> 
  </book>  
  <book id="2"> 
    <name>安徒生童话</name>  
    <year>2004</year>  
    <price>77</price>  
    <language>english</language> 
  </book> 
</bookstore>

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<book> booklist = new arraylist<book>();
    
    public arraylist<book> 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<book> booklist = new arraylist<book>();
    
    public arraylist<book> 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<book> booklist = new arraylist<book>();
    
    /**
     * @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<attribute> 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<book> bookslist = new arraylist<book>();
    /**
     * @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<element> booklist = rootelement.getchildren();
            
            // 继续进行解析
            for (element book : booklist) {
                
                book bookentity = new book();
                system.out.println("======开始解析第" + (booklist.indexof(book) + 1)
                        + "书======");
                // 解析book的属性集合
                list<attribute> 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<element> 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<book> booklists = new arraylist<book>();
        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<book> bookslist = new arraylist<book>();
        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<org.jdom2.element> booklist = rootelement.getchildren();
            for (org.jdom2.element book : booklist) {
                book bookentity = new book();
                list<attribute> attrlist = book.getattributes();
                for (attribute attr : attrlist) {
                    string attrname = attr.getname();
                    string attrvalue = attr.getvalue();
                    if (attrname.equals("id")) {
                        bookentity.setid(attrvalue);
                    }
                }
                list<org.jdom2.element> 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<book> bookslist = new arraylist<book>();
        saxreader reader = new saxreader();
        try {
            org.dom4j.document document = reader.read(new file("books.xml"));
            org.dom4j.element bookstore = document.getrootelement();
            list<org.dom4j.element> bookeles = bookstore.elements();
            for (org.dom4j.element book : bookeles) {
                book bookentity = new book();
                list<org.dom4j.attribute> bookattrs = book.attributes();
                for (org.dom4j.attribute attr : bookattrs) {
                    if (attr.getname().equals("id")) {
                        bookentity.setid(attr.getvalue());
                    }
                }
                list<org.dom4j.element> 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