• 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

    <?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

  • 相关阅读:
    [APIO2014]序列分割
    [HNOI2008]玩具装箱TOY
    [ZJOI2007]时态同步
    [FJOI2014]最短路径树问题
    [IOI2011]Race
    [国家集训队]聪聪可可
    矩阵加速递推
    Codeforces Round #669 题意及思路
    Codeforces Round #670 题意及思路
    Codeforces Round #671 题意及思路
  • 原文地址:https://www.cnblogs.com/WUXIAOCHANG/p/10655256.html
Copyright © 2020-2023  润新知