xml小伙伴们并不陌生,xml是可扩展标记语言,标准通用标记语言语言的子集,是一种用来标记电子文件使其具有结构性的标记语言。我们知道xml可以用dom与sax等方法进行解析,但是xml为什么要解析呢?为什么html就不用解析?小伙伴们可以思考一下,我们知道xml和html都是标签化的代码,其实也都是网页的一种写法,但是浏览器决定了显示什么,也就是浏览器直接解析html的基本标签,目前来说xml从一种网页应用,走向了一种格式化信息的应用,因为,我们需要使用xml里的这些信息,所以我们需要解析她,因为她的那些格式标签不是我们所需要的,我们需要的标签里的那些内容,从标签来判断这些内容是什么类型的内容,就放在什么地方,这个过程就是解析。java中解析xml的方式有四种,分别是dom、sax、jdom、dom4j,这篇博文,小编主要介绍一下dom4j解析xml文件,其他解析方式,小编也会一一进行简单介绍。
dom4j解析xml文件
dom4j是一个Java的XML API,是jdom的升级品,用来读写XML文件的。dom4j是一个十分优秀的JavaXML API,具有性能优异、功能强大和极其易使用的特点,它的性能超过sun公司官方的dom技术,同时它也是一个开放源代码的软件,可以在SourceForge上找到它。在IBM developerWorks上面还可以找到一篇文章,对主流的Java XML API进行的性能、功能和易用性的评测,所以可以知道dom4j无论在哪个方面都是非常出色的。如今可以看到越来越多的Java软件都在使用dom4j来读写XML,特别值得一提的是连Sun的JAXM也在用dom4j。这已经是必须使用的jar包, Hibernate也用它来读写配置文件。
我们采用的配置文件是xml,以前也使用propert文件,propert的功能不是很强大,现在使用的不是很多,大部分的配置都指向了xml文件,xml文件比较强大,所以,我们把数据库里面的配置配到xml文件里面,让小伙伴了解xml文件怎么编写,怎么配置,怎么读取,xml文件如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<config>
<db-info>
<driver-name>com.mysql.jdbc.Driver</driver-name>
<url>jdbc:mysql:///shop</url>
<user-name>root</user-name>
<password>123456</password>
</db-info>
</config>
名字和标签小伙伴们可以根据自己的喜好进行命名,xml的解析方式有dom、sax、jdom、dom4j,她们都是解析xml的工具,其中sax解析是针对事件进行解析,效率较高,而最常用的是dom解析,也就是从根元素开始对xml进行解析,因为是从头开始,所以当文档很大时,有时效率不高,另外修改删除也不是很方面,jdom和dom4j用起来差不多,就是方法有一点不同,接着我们以dom4j解析为例,代码如下所示:
package com.bjpowernode.drp.util;
import java.io.InputStream;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/**
* 解析单例模式sys-config.xml文件
* @author 丁国华
*
*/
public class XmlConfigReader {
//恶汉式,预先加载
/* private static XmlConfigReader instance = new XmlConfigReader();
private XmlConfigReader(){
}
public static XmlConfigReader getInstance(){
return instance;
}
*/
//懒汉式(延迟加载)真正用到的时候才new
private static XmlConfigReader instance=null;
//保存jdbc相关配置信息
private JdbcConfig jdbcConfig = new JdbcConfig();
private XmlConfigReader(){
SAXReader reader = new SAXReader();
InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("sys-config.xml");
try {
Document doc = reader.read(in);
//取得jdbc相关配置信息
Element driverNameElt = (Element)doc.selectObject("/config/db-info/driver-name");
Element urlElt = (Element)doc.selectObject("/config/db-info/url");
Element userNameElt = (Element)doc.selectObject("/config/db-info/user-name");
Element passwordElt = (Element)doc.selectObject("/config/db-info/password");
//设置jdbc的相关配置
jdbcConfig.setDriverName(driverNameElt.getStringValue());
jdbcConfig.setUrl(urlElt.getStringValue());
jdbcConfig.setUserName(userNameElt.getStringValue());
jdbcConfig.setPassword(passwordElt.getStringValue());
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static synchronized XmlConfigReader getInstance(){
if(instance ==null){
instance = new XmlConfigReader();
}
return instance;
}
/**
* 返回jdbc相关配置
* @return
*/
public JdbcConfig getJdbcConfig(){
return jdbcConfig;
}
public static void main(String[] args) {
JdbcConfig jdbcConfig = XmlConfigReader.getInstance().getJdbcConfig();
System.out.println(jdbcConfig);
}
}
虽然 DOM4J 代表了完全独立的开发结果,但最初,它是 JDOM 的一种智能分支。它合并了许多超出基本 XML 文档表示的功能,包括集成的 XPath 支持、XML Schema 支持以及用于大文档或流化文档的基于事件的处理。它还提供了构建文档表示的选项,它通过 DOM4J API 和标准 DOM 接口具有并行访问功能。从 2000 下半年开始,它就一直处于开发之中。优点:
a、大量使用java集合类,方便java开发人员,同时提供一些提高性能的替代方法;
b、支持xpath;
c、性能好。
缺点:
a、大量使用了接口,API比较复杂。
介绍了DOM4j解析xml文件的方式,接着,我们来看一下其她的三种方式,dom、sax以及jdom。
DOM解析xml文件
DOM模式解析xml,是把整个xml文档当成一个对象来处理,先把整个文档当成一个对象来处理,会先把整个文档读入到内存里,是基于树的结构,通常需要加载整个文档以及构造DOM树,然后才开始工作。
DOM 是用与平台和语言无关的方式表示 XML 文档的官方 W3C 标准。DOM 是以层次结构组织的节点或信息片断的集合。这个层次结构允许开发人员在树中寻找特定信息。分析该结构通常需要加载整个文档和构造层次结构,然后才能做任何工作。由于它是基于信息层次的,因而 DOM 被认为是基于树或基于对象的。DOM 以及广义的基于树的处理具有几个优点。
首先,由于树在内存中是持久的,因此可以修改它以便应用程序能对数据和结构作出更改。它还可以在任何时候在树中上下导航,而不是像 SAX 那样是一次性的处理。DOM 使用起来也要简单得多。另一方面,对于特别大的文档,解析和加载整个文档可能很慢且很耗资源,因此使用其他手段来处理这样的数据会更好。这些基于事件的模型,比如 SAX。 举例说明,一下是xml文件,代码如下所示:
<?xml version="1.0" encoding="ISO-8859-1"?>
<bookstore>
<book category="children">
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="cooking">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="web">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
<book category="web">
<title lang="en">XQuery Kick Start</title>
<author>James McGovern</author>
<author>Per Bothner</author>
<author>Kurt Cagle</author>
<author>James Linn</author>
<author>Vaidyanathan Nagarajan</author>
<year>2003</year>
<price>49.99</price>
</book>
</bookstore>
解析如下所示:
package com.example.xml.dom;
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
public class DomTest1
{
public static void main(String[] args) throws Exception
{
// step 1:获得DOM解析器工厂
// 工厂的作用是创建具体的解析器
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// step 2:获得具体的dom解析器
DocumentBuilder db = dbf.newDocumentBuilder();
// step 3:解析一个xml文档,获得Document对象(根节点)
// 此文档放在项目目录下即可
Document document = db.parse(new File("books.xml"));
// 根据标签名访问节点
NodeList list = document.getElementsByTagName("book");
System.out.println("list length: " + list.getLength());
// 遍历每一个节点
for (int i = 0; i < list.getLength(); ++i)
{
System.out.println("----------------------");
// 获得元素,将节点强制转换为元素
Element element = (Element) list.item(i);
// 此时element就是一个具体的元素
// 获取子元素:子元素title只有一个节点,之后通过getNodeValue方法获取节点的值
String content0 = element.getElementsByTagName("title").item(0)
.getNodeValue();
System.out.println(content0);// 此处打印出为null
// 因为节点getNodeValue的值永远为null
// 解决方法:加上getFirstChild()
String content = element.getElementsByTagName("title").item(0)
.getFirstChild().getNodeValue();
System.out.println("title: " + content);// 此处打印出书名
// 后面类似处理即可:
content = element.getElementsByTagName("author").item(0)
.getFirstChild().getNodeValue();
System.out.println("author: " + content);
content = element.getElementsByTagName("year").item(0)
.getFirstChild().getNodeValue();
System.out.println("year: " + content);
content = element.getElementsByTagName("price").item(0)
.getFirstChild().getNodeValue();
System.out.println("price: " + content);
}
}
}
使用dom解析xml有什么优缺点呢,如下所示:
优点:
a、允许应用程序对数据和结构做出更改;
b、访问是双向的,可以在任何时候在树中上下导航,获取和操作任意部分的数据。
缺点:
a、通常需要加载整个xml文档来构造层次结构,消耗资源大。
小编寄语:由于博文篇幅的原因,xml解析方式,小编就暂时介绍dom4j和dom的两种方式,在下篇博文中,小编将继续介绍xml解析方式sax和jdom,精彩未完待续......