xml解析器

爲了讓我們的應用程序不依賴於具體的解析器,讓我們以統一的接口來訪問XML文檔,Sun公司開發了JAXP(Java API For XML Processing)API。

   JAXP沒有擴充解析器新的功能,它是對解析器的一個封裝,使開發人員能夠獨立於具體的解析器,這樣我們就可以在應用程序中任意更換解析器,而不用更改應用程序代碼。現在主流的解析器都支持DOM和SAX,所以JAXP也都支持。JAXP現在的版本是1.3包含在JDK5.0之中。

    javax.xml包及子包,org.w3c.dom包及子包,org.xml.sax包及子包。javax.xml包及子包主要是獲取解析器的實例,獲取到解析器實例後就可以對XML進行讀取,如果我們使用DOM解析,那麼就使用org.w3c.dom包及子包中的接口或者類,反之使用org.xml.sax包及子包中的接口或者類。那怎麼通過JAXP獲取解析器實例呢?

    在javax.xml.parsers這個包中提供了四個類DocumentBuilder、DocumentBuilderFactory、SAXParser、SAXParserFactory 前兩個是獲取DOM解析器實例的,後兩個是獲取SAX解析器實例的。

一、獲取DOM解析器實例

Java代碼
  1. package test;  
  2. import java.io.*;  
  3. import javax.xml.parsers.*;  
  4. import org.w3c.dom.Document;  
  5. public class JAXPTest {  
  6.     public static void main(String[] args) {  
  7.         try {  
  8.             DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();  
  9.             DocumentBuilder builder = factory.newDocumentBuilder();  
  10.             Document document = builder.parse(new FileInputStream("my.xml"));  
  11.         } catch (Exception e) {  
  12.             e.printStackTrace();  
  13.         }  
  14.     }  
  15. }  
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對象就是XML文檔樹,XML文檔的數據就在此對象中。

二、更改解析器

更改 JAXP 工廠類使用的解析器很容易。更改解析器實際上意味着更改解析器工廠,因爲所有 SAXParser 和DocumentBuilder 實例都來自這些工廠。工廠確定加載哪個解析器,所以必須更改工廠。要更改 SAXParserFactory接口的實現,請設置 Java 系統特性 javax.xml.parsers.SAXParserFactory。如果未定義此特性,則返回默認實現(不管開發商指定哪個解析器)。同一規則適用於所使用的 DocumentBuilderFactory 實現。在這種情況下,將會查詢 javax.xml.parsers.DocumentBuilderFactory 系統特性。

三、JAXP API怎樣加載解析器

1、使用系統屬性
    如果我們在調用DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();代碼前設置了系統屬性,如下:
System.setProperty("javax.xml.parsers.DocumentBuilderFactory","org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
那麼JAXP就會使用你提供的解析器。設置系統屬性還可以使用另外一種方式,運行該類的時候使用-D參數,如:java -Djavax.xml.parsers.DocumentBuilderFactory=org.apache.xerces.jaxp.DocumentBuilderFactoryImpl  coresun.cn.JAXPTest

2、在JAVA_HOME\JRE\lib文件夾下建立jaxp.properties文件,在文件中添加如下內容:
javax.xml.parsers.DocumentBuilderFactory=org.apache.xerces.jaxp.DocumentBuilderFactoryImpl

3、查找解析器jar文件的META-INF\services目錄
    在此目錄下如果含有javax.xml.parsers.DocumentBuilderFactory文件,則通過此文件的內容加載解析器。

4、如果前三種方式都沒有找到解析器,JAXB使用缺省的解析器Apache Xerces(JAXP 1.1 捆綁了Apache Crimson)。

下面是一篇關於JAXP有趣的文章《XML api折射出sun與IBM的恩仇》,可供參考一下,原文地址: http://www.w3china.org/blog/more.asp?name=hongrui&id=23698

最初的xml解析器是sun的Crimson和IBM的Xerces,這兩個開源項目都捐給了apache組織,後來Xerces發展很快,Crimon基本沒有人使用。
1.4 版本起,用於 XML 處理的 Java API 就已經加入了Java 2 平臺中。 利用該 API,可通過一系列標準的 Java 平臺 API 來處理 XML 文檔。
因此,也就無需另外添加 XML 處理包了。sun的JDK1.4使用Crimson,IBM的JDK使用Xerces。
如果打算把sun 的jdk程序移植到IBM的JDK下,注意解析器不同,XML處理會出問題。這就說明了java不是“一次編譯,到處運行”,而是“一次編譯,到處調試”。
如果你把IBM的JDK移植到SUN的JDK下,即使把Xerces包引入CLASSPATH,JDK還是使用Crimson,不信你運行java -verbose試一試。
解決的辦法就是在在JRE\lib\目錄下,建立一個jaxp.properties的文件,
內容如下:
    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規範,JSR 206 Java API for XML Processing(JAXP) 1.3,他已經由JDK1.5實現。
JAXP實現了XPath,但是xalan的org.apache.xpath.XPathAPI 類已經移植到了 JRE 1.5 中,重構爲com.sun.org.apache.xpath.internal.XPathAPI。 
如果在以前的JDK中,使用含 XPathAPI 類的 jar,例如 xalan-2.4.1.jar。 將該 jar 加入到 CLASSPATH(類路徑)。

W3C的DOM標準API非常難用,於是有人開發 Java專用的XML API,這就是jdom=java+DOM。其中一部分人,去開發dom4j,這個不是非常標準,但是速度很快。
使用JDOM隱含服務器風險,因爲JBoss和Webphere都是基於JDOM開發的,在這兩個服務器下使用JDOM,必須進行相應的設置,而且你的JDOM版本必須與服務器使用的相近,
因爲JVM只加載一份相同的類,服務器優先加載自己使用的JDOM,你開發用的JDOM不會被加載,你的應用就會出錯。
使用Dom4J隱含工程問題,主要是hibernate,如果你開發的項目和hibernate合併,Dom4J版本不兼容的話,尋找dom4j相同版本hibernate,或者你改程序適應hibernate的Dom4j。
java沒有windows的DLL地獄,但是java的jar地獄有過而無不及啊。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章