java的xml学习[DOM4J方式解析XML文档]

来源:互联网 发布:矩阵a 4 1 2 编辑:程序博客网 时间:2024/04/29 06:34

  使用这种方式解析XML文档可以分为两步:

        1.    创建一个SAXReader对象reader;

        2.    通过reader对象的read方法加载xml文件,获取Document对象。

    首先从其dom4j官方网站下载dom4j-1.6.1.zip,解压得到如下文件:

http://img.mukewang.com/54db4e9f00012c6e06650239.jpg

    在我们的项目中建立一个lib目录,将dom4j-1.6.1.jar拷贝至该目录,按照前面的方法Build Path。实现如下(解析的时候将XML文档中的数据输出到控制台并保存book对象到ArrayList中):

import java.io.File;import java.util.ArrayList;import java.util.Iterator;import java.util.List; import org.dom4j.Attribute;import org.dom4j.Document;import org.dom4j.DocumentException;import org.dom4j.Element;import org.dom4j.io.SAXReader;import org.xml.parser.Book; public class DOM4JTest {    private static int bookIndex = 0;    private static Book b = null;    private static ArrayList<Book> bookList = new ArrayList<Book>();     public static void main(String[] args) {        dom4jParser();    }     public static void dom4jParser() {        // 1.创建一个SAXReader对象reader        SAXReader reader = new SAXReader();        try {            // 2.通过reader对象的read方法加载xml文件,获取Document对象            Document document = reader.read(new File("books.xml"));            Element bookStore = document.getRootElement();// 通过document对象获取根节点bookstore            // 获取根节点的子节点的相关信息            Iterator iterator = bookStore.elementIterator();// 通过Element对象的elementIterator方法获取迭代器            // 遍历迭代器,获取bookstore中的节点(book)            while (iterator.hasNext()) {                bookIndex++;                System.out                    .println("******** 开始遍历第" + bookIndex + "本书 ********");                b = new Book();                Element book = (Element) iterator.next();                // 获取book的属性名和属性值                List<Attribute> bookAttrs = book.attributes();                for (Attribute attribute : bookAttrs) {                    System.out.println("属性名:" + attribute.getName() + "-属性值:"                        + attribute.getValue());                    if ("id".equals(attribute.getName())) {                        b.setId(attribute.getValue());                    }                }                // 获取book的子节点                Iterator it = book.elementIterator();                while (it.hasNext()) {                    Element bookChild = (Element) it.next();                    System.out.println("节点名:" + bookChild.getName() + "-节点值:"                        + bookChild.getStringValue());                    if ("name".equals(bookChild.getName())) {                        b.setName(bookChild.getStringValue());                    } else if ("author".equals(bookChild.getName())) {                        b.setAuthor(bookChild.getStringValue());                    } else if ("year".equals(bookChild.getName())) {                        b.setYear(bookChild.getStringValue());                    } else if ("price".equals(bookChild.getName())) {                        b.setPrice(bookChild.getStringValue());                    } else if ("language".equals(bookChild.getName())) {                        b.setLanguage(bookChild.getStringValue());                    }                }                bookList.add(b); // 将book对象添加到bookList集合中                System.out.println("******** 结束遍历第 " + bookIndex                    + "本书 ********\n");            }            // 输出ArrayList中的book            System.out.println("ArrayList中一共有" + bookList.size() + "本书!");            for (Book book : bookList) {                System.out.println(book);            }        } catch (DocumentException e) {            e.printStackTrace();        }    }}

运行结果:

http://img.mukewang.com/54db50f800011aac07880421.jpg

【4种XML解析方式的比较】

    http://img.mukewang.com/54db513b00014ec410490260.jpg

    其中DOM是W3C官方提供的解析方式,是一种文档驱动的解析方式,将XML文件整个加载到内存,形成一颗文档树(Document Tree)。是一种官方的标准,仅仅是在Java中使用,在其他编程语言,例如Javascript、ASP.NET中也有相关的对XML DOM的支持。SAX解析是一种最快的解析方式,广泛应用于资源有限的环境,例如:Android提供SAX方式解析XML文档;DOM4J方式是非常优秀的Java XML API,java的SSH框架中Hibernate就是使用这种方式解析的XML,是比较推荐的一种解析方式。

    下面通过一段代码来测试4种方式解析XML的性能差异:

首先新建一个JUnit:在项目中右键Build Path->Add Libraries->JUint->next->JUnit4-finish。

http://img.mukewang.com/54db54680001e14006970620.jpg

    完成后会出现如下:

http://img.mukewang.com/54db55ad0001e99402750338.jpg

    将以上4种解析XML文件的方式整合到一个类中(这里要注意一点,因为org.dom4j.Document与org.w3c.dom.Document等等他们是相同的类但是属于不同的包,我们不可能将两个一起导入,所以有一些需要使用完成的类名【包名.类名的形式】),我们在每种方法解析开始的时候获取系统的时间(long类型的毫秒数),在每种方法解析结束的时候再获取系统时间,就可以得到该方法解析所花费的时间(注意:在本测试程序中针对每一种解析方式,我们仅仅读取XML文件中的数据并保存至Java对象,为了便于区分各种解析方式的差异,我们将books.xml拓展至12,3267行(2.59MB))。测试方法需要使用@Test Annotation(@Test表示这个方法是JUnit测试时候会运行的)

import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.io.InputStream;import java.util.ArrayList;import java.util.Iterator;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.Element;import org.jdom2.JDOMException;import org.jdom2.input.SAXBuilder;import org.junit.Test;import org.w3c.dom.Document;import org.w3c.dom.NamedNodeMap;import org.w3c.dom.Node;import org.w3c.dom.NodeList;import org.xml.parser.Book;import org.xml.parser.SAX.SAXParserHandler;import org.xml.sax.SAXException; public class PerformanceTest {    @Test    public void testPerformance() {    System.out.println("4种XML解析方式的性能比较(针对books.xml解析):");    long startTime = System.currentTimeMillis();    domParser();    System.out.println("DOM方式解析耗时:\t"        + (System.currentTimeMillis() - startTime) + "ms");    startTime = System.currentTimeMillis();    saxParser();    System.out.println("SAX方式解析耗时:\t"        + (System.currentTimeMillis() - startTime) + "ms");    startTime = System.currentTimeMillis();    jdomParser();    System.out.println("JDOM方式解析耗时:\t"        + (System.currentTimeMillis() - startTime) + "ms");    startTime = System.currentTimeMillis();    dom4jParser();    System.out.println("DOM4J方式解析耗时:\t"        + (System.currentTimeMillis() - startTime) + "ms");    }     public static void domParser() {    Book book = null;    ArrayList<Book> books = 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++) {        book = new Book();        Node bookNode = (Node) bookList.item(i);        NamedNodeMap attributes = bookNode.getAttributes();         // 遍历book节点的属性        for (int j = 0; j < attributes.getLength(); j++) {            Node attribute = attributes.item(j);            if ("id".equals(attribute.getNodeName())) {            book.setId(attribute.getNodeValue());            }        }         // 解析book节点的子节点        NodeList childNodes = bookNode.getChildNodes();        // 遍历childNodes获取每个节点的节点名和节点值        for (int j = 0; j < childNodes.getLength(); j++) {            // 区分textNode和elementNode            if (childNodes.item(j).getNodeType() == Node.ELEMENT_NODE) {            if ("name".equals(childNodes.item(j).getNodeName())) {                book.setName(childNodes.item(j).getFirstChild()                    .getNodeValue());            } else if ("author".equals(childNodes.item(j)                .getNodeName())) {                book.setAuthor(childNodes.item(j).getTextContent());            } else if ("year".equals(childNodes.item(j)                .getNodeName())) {                book.setYear(childNodes.item(j).getTextContent());            } else if ("price".equals(childNodes.item(j)                .getNodeName())) {                book.setPrice(childNodes.item(j).getTextContent());            } else if ("language".equals(childNodes.item(j)                .getNodeName())) {                book.setLanguage(childNodes.item(j)                    .getTextContent());            }            }        }        books.add(book);// 结束一本书的遍历的时候将其加入ArrayList中        }     } catch (ParserConfigurationException e) {        e.printStackTrace();    } catch (SAXException e) {        e.printStackTrace();    } catch (IOException e) {        e.printStackTrace();    }    }     public static void saxParser() {    // 1.获取一个SAXParserFactory的实例    SAXParserFactory factory = SAXParserFactory.newInstance();    try {        // 2.通过factory获取SAXParser实例        SAXParser parser = factory.newSAXParser();        // 3.创建一个SAXParserHandler对象        SAXParserHandler handler = new SAXParserHandler();        // 4.通过SAXParser对象的parse(String uri,DefaultHandler dh)方法解析xml文件        parser.parse("books.xml", handler);         /* 将XML文件中的数据保存在Book对象中并将对象添加到ArrayList中,遍历ArrayList */        ArrayList<Book> books = handler.getBookList();     } catch (ParserConfigurationException e) {        e.printStackTrace();    } catch (SAXException e) {        e.printStackTrace();    } catch (IOException e) {        e.printStackTrace();    }    }     public static void jdomParser() {    ArrayList<Book> booksList = new ArrayList<Book>();    // 1.创建一个SAXBuilder对象    SAXBuilder saxBuilder = new SAXBuilder();     InputStream in;    try {        // 2.创建一个输入流,将xml文件加载到输入流        in = new FileInputStream("books.xml");        // 3.通过SAXBuilder的build方法将输入流加载到SAXBuilder中        org.jdom2.Document document = saxBuilder.build(in);        // 4.通过Document对象获取xml文件的根节点        Element rootElement = document.getRootElement();        // 5.根据根节点获取子节点的List集合        List<Element> bookList = rootElement.getChildren();        // 使用循环对bookList进行遍历        for (Element book : bookList) {        Book bookEntity = new Book();         // 不知道属性的个数和属性名的时候        List<Attribute> attrList = book.getAttributes();        // 遍历book的属性集合        for (Attribute attribute : attrList) {            if ("id".equals(attribute.getName())) {            bookEntity.setId(attribute.getValue());            }        }        // 对book节点的子节点的节点名和节点值进行遍历        List<Element> bookChilds = book.getChildren();        for (Element child : bookChilds) {            if ("name".equals(child.getName())) {            bookEntity.setName(child.getValue());            } else if ("author".equals(child.getName())) {            bookEntity.setAuthor((child.getValue()));            } else if ("year".equals(child.getName())) {            bookEntity.setYear((child.getValue()));            } else if ("price".equals(child.getName())) {            bookEntity.setPrice(child.getValue());            } else if ("language".equals(child.getValue())) {            bookEntity.setLanguage(child.getValue());            }        }        booksList.add(bookEntity);        }     } catch (FileNotFoundException e) {        e.printStackTrace();    } catch (JDOMException e) {        e.printStackTrace();    } catch (IOException e) {        e.printStackTrace();    }    }     public static void dom4jParser() {    ArrayList<Book> bookList = new ArrayList<Book>();    Book b = null;    // 1.创建一个SAXReader对象reader    SAXReader reader = new SAXReader();    try {        // 2.通过reader对象的read方法加载xml文件,获取Document对象        org.dom4j.Document document = reader.read(new File("books.xml"));        org.dom4j.Element bookStore = document.getRootElement();        // 获取根节点的子节点的相关信息        Iterator iterator = bookStore.elementIterator();        // 遍历迭代器,获取bookstore中的节点(book)        while (iterator.hasNext()) {        b = new Book();        org.dom4j.Element book = (org.dom4j.Element) iterator.next();        // 获取book的属性名和属性值        List<org.dom4j.Attribute> bookAttrs = book.attributes();        for (org.dom4j.Attribute attribute : bookAttrs) {            if ("id".equals(attribute.getName())) {            b.setId(attribute.getValue());            }        }        // 获取book的子节点        Iterator it = book.elementIterator();        while (it.hasNext()) {            org.dom4j.Element bookChild = (org.dom4j.Element) it.next();            if ("name".equals(bookChild.getName())) {            b.setName(bookChild.getStringValue());            } else if ("author".equals(bookChild.getName())) {            b.setAuthor(bookChild.getStringValue());            } else if ("year".equals(bookChild.getName())) {            b.setYear(bookChild.getStringValue());            } else if ("price".equals(bookChild.getName())) {            b.setPrice(bookChild.getStringValue());            } else if ("language".equals(bookChild.getName())) {            b.setLanguage(bookChild.getStringValue());            }        }        bookList.add(b); // 将book对象添加到bookList集合中        }     } catch (DocumentException e) {        e.printStackTrace();    }    }}

http://img.mukewang.com/54db60090001b13905780117.jpg

    SAX解析的性能是最高的,然后是DOM4J解析,最后是DOM解析和JDOM解析,在实际应用中我们一般采用DOM4J的方式进行XML的解析。



0 0
原创粉丝点击