君子博学而日参省乎己 则知明而行无过矣

博客园 首页 新随笔 联系 订阅 管理

为了让我们的应用程序不依赖于具体的解析器,让我们以统一的接口来访问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. }  


以上代码的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地狱有过而无不及啊。
 
JAXP 全面介绍
http://www.ibm.com/developerworks/cn/xml/x-jaxp/index.html
http://www.ibm.com/developerworks/cn/xml/x-jaxp2/
posted on 2013-03-07 03:19  刺猬的温驯  阅读(2933)  评论(0编辑  收藏  举报