论坛首页 Java企业应用论坛

xml解析器加载的顺序

浏览 3647 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2010-02-04  
这两天在用java做XML解析的时候遇到了一个比较棘手的问题
由于我需要将xml写入文件,于是乎我在工程中到如了第三方包crimon.jar

<TR>
<TD valign="top" nowrap="">
<P>02320403012447</P></TD>
<TD valign="top" nowrap="">
<P>黄陈菊</P></TD>
<TD valign="top" nowrap="">
<P>河海大学</P></TD>
<TD valign="top" nowrap="">
<P>广播电视新闻学</P></TD>
<TD valign="top" nowrap="">
<P>本科一批</P></TD>
<TD valign="top" nowrap="">
<P>第一志愿</P></TD>
<TD valign="top" nowrap="">
<P>统招</P></TD>
<TD valign="top" nowrap="">
<P>16-Aug-02 00:00:00</P></TD>
<TD valign="top" nowrap="">
<P>571</P></TD>
<TD valign="top" nowrap="">
<P>571</P></TD></TR>
<TR>

我想获取其中的名字,于是乎我进行了
如此解析:
首先进行解析工厂的初始化,并获得dom

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
db = dbf.newDocumentBuilder();
Document doc = db.parse(new File("**.xml"));
Element root = document.getDocumentElement();
。。。。

在顺利获得了包含名字的<P>节点后,假设为Element p
String name=p.getChildNodes().item(1).getTextContent();
我想这样就能解析出名字了,但程序却一直报出如下错误
Exception in thread "main" java.lang.AbstractMethodError: org.apache.crimson.tree.ElementNode.getTextContent()Ljava/lang/String;

这个问题很诡异,因为Node明明就有getTextContent()方法啊,怎么会报错呢。。。
看样子一开始获得Document对象的时候就错了,难道生成的工厂错了

于是乎,我打印工厂看看
System.out.println(dbf);
结果:
org.apache.crimson.jaxp.DocumentBuilderFactoryImpl@fd13b5


奇怪。。。。。怎么会出现crimon的字眼,我明明就是用的jdk自带的工厂啊。。。。应该这样的结果才对啊com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl@76cbf7


后来我通过阅读JAXP的源码才知道,工厂类首先会根据java系统属性进行寻找,然后在根据JRE\lib\jaxp.properties中定义的实现类寻找,最后什么都找不到的话,就用Crimson。注意Crimons是由Bootstrap Class Loader来load的,如果你不通过上面两个方法来改变工厂的寻找顺序,那么铁定用Crimson了,看样子这才是问题出现的原因

于是,我在程序中添加了这么一行
System.setProperty("javax.xml.parsers.DocumentBuilderFactory","com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");

问题迎刃而解。。。。


既然有了Xerces的实现,那为什么还要Crimson呢,后来在别人博客中找到如下解释:

Crimson来自于Sun捐赠给Apache的ProjectX项目,Xerces来自IBM捐赠给Apache的XML4J项目,结果Xerces胜出,成了Apache XML小组全力开发的XML API,而Crimon已经早就不做了,如今Xerces名满天下,到处都是在用Xerces DOM和SAX解析器,只有Sun不服气,非要在JDK1.4里面使用过时的Crimson,让人感觉像是在赌气一样,真是让人可怜又可气!不过IBM发行JDK用的XML 解析器自然是Xerces。 www.dedecms.com
由于JDK的Class Loader的优先级关系,当你采用JAXP编写XML程序的时候,即使把Xerces包引入CLASSPATH,JDK还是会顽固的使用 Crimson

至此,真相大白!
   发表时间:2010-02-04  
通过meta-inf里面加services的话比在程序中指明要方便点。

详细可以看这里
http://java.sun.com/developer/EJTechTips/2003/tt0311.html
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics