Java之DOM,SAX,JDOM,DOM4J,四种解析xml方法比较

时间:2023-02-26 20:20:10
4种解析方式的比较
1.DOM解析   
优点:a.形成了树结构,直观好理解,代码更易编写
         b.解析过程中树结构保留在内存中,方便修改
缺点:
        a.当xml文件较大时,对内存耗费比较大,容易影响解析性能并且造成内存溢出


2.SAX解析
优点:a.采用事件驱动模式,对内存耗费比较小
         b.适用于只需要处理xml中数据时
缺点:a.不易编码(需要借助handler来进行解析)
         b.很难同时访问同一个xml中的多处不同数据(事件有先后顺序的)


3.JDOM解析
    a.仅使用具体类而不使用接口
    b.API大量使用了Collections类


4.DOM4J
    a.JDOM的一种智能分支,它合并了许多超出基本XML文档表示的功能
    b.DOM4J使用接口和抽象基本类方法,是一个优秀的Java XML API
    c.具有性能优异、灵活性好、功能强大和极易使用的特点

    d.是一个开源代码的软件


性能比较

package parserTest;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Iterator;
import java.util.List;

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

import org.dom4j.io.SAXReader;
import org.jdom.input.SAXBuilder;
import org.junit.Test;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import handler.SAXParserHandler;
import jDomTest.Book;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;

public class ParserTest {
	@SuppressWarnings({ "unchecked", "rawtypes", "unused" })
	public void Dom4jToXML() throws Exception {
		// 解析books.xml文件
		// 创建SAXReader的对象reader
		SAXReader reader = new SAXReader();
		// reader对象的read方法加载books.xml文件,获取document对象
		Document document = (Document) reader.read(new File("books.xml"));
		// 通过document对象获取根节点bookstore
		Element bookStore = document.getRootElement();
		// 遍历迭代器,获取根节点中的信息(书籍)
		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();
				// 获取book子节点的属性名和属性值
				//System.out.println("节点名:" + bookchild.getName() + "----节点值:" + bookchild.getName());
			}

			//System.out.println("----------结束遍历某本书------------");
		}
	}

	@SuppressWarnings("unused")
	public void DomToXML() throws Exception {
		// 创建一个DocumentBuilderFactory的对象
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		// 创建一个DocumentBuilder对象
		DocumentBuilder db = dbf.newDocumentBuilder();
		// 通过DocumentBuilder对象的parse(String fileName)方法解析xml文件
		org.w3c.dom.Document document = db.parse("books.xml");
		// 获取所有book节点的集合
		NodeList bookList = ((org.w3c.dom.Document) 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节点,notelist的索引值从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节点的子节点
			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("------------------结束遍历-------------------");
		}
	}

	public void SAXToXML() throws Exception {
		// 获取一个SAXParserFactory的实例
		javax.xml.parsers.SAXParserFactory factory = SAXParserFactory.newInstance();
		// 通过factory获取SAXParser实例
		javax.xml.parsers.SAXParser parser = factory.newSAXParser();
		// 创建SAXParserHandler对象
		handler.SAXParserHandler handler = new SAXParserHandler();
		parser.parse("books.xml", handler);
	}

	@SuppressWarnings("unchecked")
	public void JDomToXML() throws Exception {
		// 进行对books.xml文件的JDOM解析
		// 准备工作
		// 1.创建一个SAXBuilder的对象
		SAXBuilder saxBuilder = new SAXBuilder();
		// 2.创建一个输入流,将xml文件加载到输入流中
		InputStream in = new FileInputStream("books.xml");
		// InputStreamReader isr= new InputStreamReader(in,"UTF-8");
		// 3.通过saxBuilder的build方法,将输入流加载到saxBuilder中
		org.jdom.Document document = saxBuilder.build(in);
		// 4.通过document对象获取xml文件的根节点
		org.jdom.Element rootElement = document.getRootElement();
		// 5.获取根节点下的子节点的List集合
		List<org.jdom.Element> bookList = ((org.jdom.Element) rootElement).getChildren();
		// 继续进行解析
		for (org.jdom.Element book : bookList) {
			// 创建一个book对象
			Book bookEntity = new Book();
			//System.out.println("------------开始解析第" + (bookList.indexOf(book) + 1) + "本书-----------");
			// 开始解析book的属性
			// 适用于我们不知道有多少属性
			List<org.jdom.Attribute> attrList = book.getAttributes();
			// 适用于我们知道子节点属性的名称直接获取其属性
			// Book.getAttributeValue("id");
			// 遍历attrList(针对于不知道book节点下属性的名称及数量)
			for (org.jdom.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<org.jdom.Element> bookChilds = book.getChildren();
			for (org.jdom.Element child : bookChilds) {
				//System.out.println("节点名:" + child.getName() + "---节点值:" + child.getValue());
			}
			//System.out.println("------------结束解析第" + (bookList.indexOf(book) + 1) + "本书-----------");
		}
	}
	@Test
	public void testPerformance() throws Exception {
		System.out.println("性能测试");
		//测试DOM的性能
		long start = System.currentTimeMillis();
		DomToXML();
		System.out.println("DOM:"+(System.currentTimeMillis()-start));
		//测试SAX的性能
		start = System.currentTimeMillis();
		SAXToXML();
		System.out.println("SAX:"+(System.currentTimeMillis()-start));
		//测试JDOM的性能
		start = System.currentTimeMillis();
		JDomToXML();
		System.out.println("JDOM:"+(System.currentTimeMillis()-start));
		//测试DOM4J的性能
		start = System.currentTimeMillis();
		Dom4jToXML();
		System.out.println("DOM4J:"+(System.currentTimeMillis()-start));
	}
	public static void main(String[] args) {
		ParserTest pt = new ParserTest();
		
	}

}
截图如下:

Java之DOM,SAX,JDOM,DOM4J,四种解析xml方法比较