為了讓我們的應(yīng)用程序不依賴于具體的解析器,讓我們以統(tǒng)一的接口來訪問XML文檔,Sun公司開發(fā)了JAXP(Java API For XML Processing)API。
JAXP沒有擴(kuò)充解析器新的功能,它是對(duì)解析器的一個(gè)封裝,使開發(fā)人員能夠獨(dú)立于具體的解析器,這樣我們就可以在應(yīng)用程序中任意更換解析器,而不用更改應(yīng)用程序代碼?,F(xiàn)在主流的解析器都支持DOM和SAX,所以JAXP也都支持。JAXP現(xiàn)在的版本是1.3包含在JDK5.0之中。
javax.xml包及子包,org.w3c.dom包及子包,org.xml.sax包及子包。javax.xml包及子包主要是獲取解析器的實(shí)例,獲取到解析器實(shí)例后就可以對(duì)XML進(jìn)行讀取,如果我們使用DOM解析,那么就使用org.w3c.dom包及子包中的接口或者類,反之使用org.xml.sax包及子包中的接口或者類。那怎么通過JAXP獲取解析器實(shí)例呢?
在javax.xml.parsers這個(gè)包中提供了四個(gè)類DocumentBuilder、DocumentBuilderFactory、SAXParser、SAXParserFactory 前兩個(gè)是獲取DOM解析器實(shí)例的,后兩個(gè)是獲取SAX解析器實(shí)例的。
一、獲取DOM解析器實(shí)例
package test;import java.io.*;import javax.xml.parsers.*;import org.w3c.dom.Document;public class JAXPTest {public static void main(String[] args) {try {DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();DocumentBuilder builder = factory.newDocumentBuilder();Document document = builder.parse(new FileInputStream("my.xml"));} catch (Exception e) {e.printStackTrace();}}}
以上代碼的document對(duì)象就是XML文檔樹,XML文檔的數(shù)據(jù)就在此對(duì)象中。
二、更改解析器
更改 JAXP 工廠類使用的解析器很容易。更改解析器實(shí)際上意味著更改解析器工廠,因?yàn)樗?SAXParser 和 DocumentBuilder 實(shí)例都來自這些工廠。工廠確定加載哪個(gè)解析器,所以必須更改工廠。要更改 SAXParserFactory 接口的實(shí)現(xiàn),請(qǐng)?jiān)O(shè)置 Java 系統(tǒng)特性 javax.xml.parsers.SAXParserFactory。如果未定義此特性,則返回默認(rèn)實(shí)現(xiàn)(不管開發(fā)商指定哪個(gè)解析器)。同一規(guī)則適用于所使用的 DocumentBuilderFactory 實(shí)現(xiàn)。在這種情況下,將會(huì)查詢 javax.xml.parsers.DocumentBuilderFactory 系統(tǒng)特性。
三、JAXP API怎樣加載解析器
1、使用系統(tǒng)屬性
如果我們?cè)谡{(diào)用DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();代碼前設(shè)置了系統(tǒng)屬性,如下:
System.setProperty("javax.xml.parsers.DocumentBuilderFactory","org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
那么JAXP就會(huì)使用你提供的解析器。設(shè)置系統(tǒng)屬性還可以使用另外一種方式,運(yùn)行該類的時(shí)候使用-D參數(shù),如:java -Djavax.xml.parsers.DocumentBuilderFactory=org.apache.xerces.jaxp.DocumentBuilderFactoryImpl coresun.cn.JAXPTest
2、在JAVA_HOME\JRE\lib文件夾下建立jaxp.properties文件,在文件中添加如下內(nèi)容:
javax.xml.parsers.DocumentBuilderFactory=org.apache.xerces.jaxp.DocumentBuilderFactoryImpl
3、查找解析器jar文件的META-INF\services目錄
在此目錄下如果含有javax.xml.parsers.DocumentBuilderFactory文件,則通過此文件的內(nèi)容加載解析器。
4、如果前三種方式都沒有找到解析器,JAXB使用缺省的解析器Apache Xerces(JAXP 1.1 捆綁了Apache Crimson)。
下面是一篇關(guān)于JAXP有趣的文章《XML api折射出sun與IBM的恩仇》,可供參考一下,原文地址: http://www.w3china.org/blog/more.asp?name=hongrui&id=23698
最初的xml解析器是sun的Crimson和IBM的Xerces,這兩個(gè)開源項(xiàng)目都捐給了apache組織,后來Xerces發(fā)展很快,Crimon基本沒有人使用。
1.4 版本起,用于 XML 處理的 Java API 就已經(jīng)加入了Java 2 平臺(tái)中。 利用該 API,可通過一系列標(biāo)準(zhǔn)的 Java 平臺(tái) API 來處理 XML 文檔。
因此,也就無需另外添加 XML 處理包了。sun的JDK1.4使用Crimson,IBM的JDK使用Xerces。
如果打算把sun 的jdk程序移植到IBM的JDK下,注意解析器不同,XML處理會(huì)出問題。這就說明了java不是“一次編譯,到處運(yùn)行”,而是“一次編譯,到處調(diào)試”。
如果你把IBM的JDK移植到SUN的JDK下,即使把Xerces包引入CLASSPATH,JDK還是使用Crimson,不信你運(yùn)行java -verbose試一試。
解決的辦法就是在在JRE\lib\目錄下,建立一個(gè)jaxp.properties的文件,
內(nèi)容如下:
javax.xml.parsers.DocumentBuilderFactory=org.apache.xerces.jaxp.DocumentBuilderFactoryImpl
javax.xml.parsers.SAXParserFactory=org.apache.xerces.jaxp.SAXParserFactoryImpl
就可以使用Xerces。
或者使用命令行
# Add the XML parser jars and set the JAXP factory names
# Crimson parser JAXP setup(default)
CLASSPATH=$CLASSPATH:../lib/crimson.jar
JAXP=-Djavax.xml.parsers.DocumentBuilderFactory=org.apache.crimson.jaxp.DocumentBuilderFactoryImpl
JAXP="$JAXP -Djavax.xml.parsers.SAXParserFactory=org.apache.crimson.jaxp.SAXParserFactoryImpl"
或
# Add the XML parser jars and set the JAXP factory names
# Xerces parser JAXP setup
CLASSPATH=$CLASSPATH:../lib/xerces.jar
JAXP=-Djavax.xml.parsers.DocumentBuilderFactory=org.apache.xerces.jaxp.DocumentBuilderFactoryImpl
JAXP="$JAXP -Djavax.xml.parsers.SAXParserFactory=org.apache.xerces.jaxp.SAXParserFactoryImpl"
最終sun還是指定JAXP規(guī)范,JSR 206 Java API for XML Processing(JAXP) 1.3,他已經(jīng)由JDK1.5實(shí)現(xiàn)。
JAXP實(shí)現(xiàn)了XPath,但是xalan的org.apache.xpath.XPathAPI 類已經(jīng)移植到了 JRE 1.5 中,重構(gòu)為com.sun.org.apache.xpath.internal.XPathAPI。
如果在以前的JDK中,使用含 XPathAPI 類的 jar,例如 xalan-2.4.1.jar。 將該 jar 加入到 CLASSPATH(類路徑)。
W3C的DOM標(biāo)準(zhǔn)API非常難用,于是有人開發(fā) Java專用的XML API,這就是jdom=java+DOM。其中一部分人,去開發(fā)dom4j,這個(gè)不是非常標(biāo)準(zhǔn),但是速度很快。
使用JDOM隱含服務(wù)器風(fēng)險(xiǎn),因?yàn)镴Boss和Webphere都是基于JDOM開發(fā)的,在這兩個(gè)服務(wù)器下使用JDOM,必須進(jìn)行相應(yīng)的設(shè)置,而且你的JDOM版本必須與服務(wù)器使用的相近,
因?yàn)镴VM只加載一份相同的類,服務(wù)器優(yōu)先加載自己使用的JDOM,你開發(fā)用的JDOM不會(huì)被加載,你的應(yīng)用就會(huì)出錯(cuò)。
使用Dom4J隱含工程問題,主要是hibernate,如果你開發(fā)的項(xiàng)目和hibernate合并,Dom4J版本不兼容的話,尋找dom4j相同版本hibernate,或者你改程序適應(yīng)hibernate的Dom4j。
java沒有windows的DLL地獄,但是java的jar地獄有過而無不及啊。
聯(lián)系客服