`
wangyang_09
  • 浏览: 96377 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

DocumentBuilder.parse() returns "[#Document: null]

    博客分类:
  • J2EE
阅读更多
出处http://topic.csdn.net/t/20050425/20/3965996.html#

首先感谢   ruby_cn(__   http://www.ruby-cn.org/   __)的blog! 
  按你说的,我删除了项目中和xml相关的所有包,一切如故。我干脆删了所有的包,除了jre和j2ee,还是如故。我将 DocumentBuilderFactory对象打印出:System.out.println(factory);令人惊讶的结果出现了:org.apache.xerces.jaxp.DocumentBuilderFactoryImpl@1ad086a。我本来也猜测一定是某个第三方的包的类继承了javax.xml.parsers.DocumentBuilderFactory,发现 javax.xml.parsers.DocumentBuilderFactory是一个抽象类,所以的确很有可能,因为抽象类是不能产生对象的。但是也留下一个疑问,程序里并没有产生继承了javax.xml.parsers.DocumentBuilderFactory的类的对象,运行时怎么会自动产生它的子类对象。难道是sevlet容器干的好事?因为抽象类不能产生对象,自动产生继承这个抽象类的对象?类似于EJB容器产生实现home、 remote接口的对象?可是现在我把第三方的包全部删除了,怎么还会输出“apache”这个字眼?这时回想起用main方法不是一切正常的吗?于是跑了一下main,又是令人惊讶的结果:org.apache.crimson.jaxp.DocumentBuilderFactoryImpl@15601ea还是“apache”的实现,但是不同的类,这个类能完好的工作。不用说,一应定是jre或j2ee里有apache的东西。结果发现在jre/lib/rt.jar里有相当多的 apache的包。这个类也在这里。我才刚刚知道原来jre里不全是sun的东西。现在的问题是为什么到了sevlet就会产生 org.apache.xerces.jaxp.DocumentBuilderFactoryImpl的对象。我找 org.apache.xerces.jaxp.DocumentBuilderFactoryImpl类,找了很久发现他在xercesImpl包里。这个包在jboss-4.0.1sp1\lib\endorsed目录下。我把xercesImpl包倒入了那个工具类所在的项目。运行main方法,果然,输出了org.apache.xerces.jaxp.DocumentBuilderFactoryImpl。看来很清楚了,和sevlet容器没关系,只要这两个类被包含在同一个项目里,就会优先产生 org.apache.xerces.jaxp.DocumentBuilderFactoryImpl对象。这是怎么回事呢,我猜想一定在 DocumentBuilderFactory的产生对象的方法有个选择逻辑。这时想到jdk是有源代码的,哈哈,太好了!察看 DocumentBuilderFactoryImpl的newInstance()方法: 
  return   (DocumentBuilderFactory)   FactoryFinder.find( 
                                  /*   The   default   property   name   according   to   the   JAXP   spec   */ 
                                  "javax.xml.parsers.DocumentBuilderFactory", 
                                  /*   The   fallback   implementation   class   name   */ 
                                  "org.apache.crimson.jaxp.DocumentBuilderFactoryImpl"); 
  他调用了FactoryFinder.find()方法。注意在这里已经看到了"org.apache.crimson.jaxp.DocumentBuilderFactoryImpl"是的,字面意思这是作为一个后备的选择,也就是找不到其他实现了javax.xml.parsers.DocumentBuilderFactory的类,那么就返回 org.apache.crimson.jaxp.DocumentBuilderFactoryImpl的对象。赶紧去看 FactoryFinder.find()方法:三段注释揭露了一切: 
  //   Use   the   system   property   first 
  //   try   to   read   from   $java.home/lib/jaxp.properties 
  //   try   to   find   services   in   CLASSPATH 
  最后都找不到当然是返回后备的org.apache.crimson.jaxp.DocumentBuilderFactoryImpl啦。 
  String   serviceId   =   "META-INF/services/"   +   factoryId; 
  打开xercesImpl包看看,果然有\META-INF\services目录。里面果然有个 javax.xml.parsers.DocumentBuilderFactory文件。打开一看文件内容果然是 org.apache.xerces.jaxp.DocumentBuilderFactoryImpl 
  。看来疑团都揭开啦。但是还有一点sevlet运行的classpath怎么会有endorsed\。打开run.bat看见:"%JAVA%"   %JAVA_OPTS%   "-Djava.endorsed.dirs=%JBOSS_ENDORSED_DIRS%"   -classpath   "%JBOSS_CLASSPATH%"   org.jboss.Main   %   看来endorsed是作为了一个java参数。好了,一切都明白了。现在要怎么解决呢。删除xercesImpl包是一定可以的但是关于 endorsed我也不懂,好像websvice要用到。关于endorsed:http://java.sun.com/j2se/1.4.2 /docs/guide/standards/     所以我不敢删。想到的办法只有System.setProperty(   "javax.xml.parsers.DocumentBuilderFactory","org.apache.crimson.jaxp.DocumentBuilderFactoryImpl"   );因为//   Use   the   system   property   first。好了,用完以后赶快System.setProperty(   "javax.xml.parsers.DocumentBuilderFactory","org.apache.xerces.jaxp.DocumentBuilderFactoryImpl"   );因为不知道jboss的那些类会用到org.apache.xerces.jaxp.DocumentBuilderFactoryImpl,所以还是要恢复过来的。好了,问题虽然解决了,但是感受到了不优雅的java。

分享到:
评论
1 楼 wbj2008wbj2008 2013-03-14  
厉害,向你学习

相关推荐

    dom4j.jar.jar

    XML用于保存及交换数据,与读取配置文件的类在同一包,或在WEB-INF(或其子目录下),// 读取配置文件获得一个输入流 InputStream is = Demo1.class....Document document = documentBuilder.parse(is);

    java.lang.AbstractMethodError: org.apache.xerces.dom.DocumentImpl.setXmlVersion问题解决方法

    首先,通过`DocumentBuilderFactory`创建一个`DocumentBuilder`实例,然后使用`parse()`方法解析XML文件。解析完成后,`normalize()`方法确保文档元素的正常格式。接着,通过`getElementsByTagName()`获取XML文档中...

    Java与XML联合编程

    Document document = builder.parse(new File("example.xml")); ``` ##### 2. SAX 解析 - **简介**:SAX是一种事件驱动的解析方式,不会一次性加载整个XML文档到内存中。当解析器在文档中遇到特定事件(如开始...

    android_中对xml_进行解析.doc

    Document doc = dBuilder.parse(inputFile); doc.getDocumentElement().normalize(); System.out.println("Root element :" + doc.getDocumentElement().getNodeName()); NodeList nList = doc....

    android解析xml源码和ppt.zip

    Document doc = builder.parse(inputStream); // 遍历和处理doc对象 ``` - SAX解析: ```java DefaultHandler handler = new MySAXHandler(); SAXParserFactory factory = SAXParserFactory.newInstance(); ...

    ParseXML实例

    Document doc = dBuilder.parse("example.xml"); doc.getDocumentElement().normalize(); NodeList nList = doc.getElementsByTagName("element_name"); for (int i = 0; i < nList.getLength(); i++) { Node n...

    Java解析XML的4中方法

    Document doc = builder.parse(file); NodeList nl = doc.getElementsByTagName("VALUE"); for (int i = 0; i < nl.getLength(); i++) { System.out.print("号码: " + doc.getElementsByTagName("NO").item(i)....

    dom4j的使用教程

    1. 加载XML文档:使用`DocumentFactory`创建`DocumentBuilder`,然后通过`DocumentBuilder`解析XML文件得到`Document`对象。 2. 查询节点:利用`XPath`接口,根据XPath表达式获取需要的节点。 3. 创建、修改节点:...

    java读取xml文件

    Document doc = dBuilder.parse("example.xml"); doc.getDocumentElement().normalize(); System.out.println("Root element :" + doc.getDocumentElement().getNodeName()); NodeList nList = doc....

    java parser xmlDocument ----Share with all of friends

    4. 解析XML文件:通过`DocumentBuilder`的`parse()`方法加载并解析XML文件,得到`Document`对象。 ```java File xmlFile = new File("path_to_your_xml_file.xml"); Document doc = builder.parse(xmlFile); ``` 5...

    xml.rar_XML读取和显示_xml_xml 解析器_读取xml并显示

    2. 创建DOM树:`DocumentBuilder`的`parse()`方法返回一个`Document`对象,这是整个XML文档的根节点。 3. 遍历DOM树:通过`Document`对象的方法,如`getElementsByTagName()`, `getFirstChild()`, `getTextContent()...

    java对xml操作的项目案例

    1. DOM解析器:Document Object Model (DOM) 是一种将整个XML文档加载到内存中形成树形结构的方法。Java中,`javax.xml.parsers.DocumentBuilderFactory` 和 `org.w3c.dom.Document` 类用于创建和操作DOM对象。例如...

    xercesimpl-2.8.1.jar

    Document doc = builder.parse("your_xml_file.xml"); Node root = doc.getDocumentElement(); System.out.println("Root element :" + root.getNodeName()); NodeList nodeList = root.getChildNodes(); for...

    JDOM使用详解及实例

    与DOM相比,JDOM的创建过程更为直接,不需要像DOM那样通过DocumentBuilderFactory和DocumentBuilder等多个步骤来构建。 JDOM还支持JAXP(Java API for XML Processing)1.1,这意味着你可以自由选择XML解析器,例如...

    java中解析xml

    Document doc = dBuilder.parse("example.xml"); doc.getDocumentElement().normalize(); System.out.println("Root element :" + doc.getDocumentElement().getNodeName()); NodeList nList = doc....

    java 处理 xml Demo

    Document document = builder.parse(new File("yourfile.xml")); // 访问根元素 Element root = document.getDocumentElement(); // 遍历元素 for (int i = 0; i < root.getChildNodes().getLength(); i++) {...

    JDOMAPI(html)

    1. **创建XML文档**: 使用`DocumentBuilder`创建一个新的`Document`实例,然后添加元素、属性等。 2. **添加元素**: `Element`类提供了`addContent(Content)`方法来添加子元素,或者使用`setAttribute(String name,...

    java操作XML文件

    它通过`DocumentBuilderFactory`创建`DocumentBuilder`,然后利用`parse`方法解析传入的字符串,生成`Document`对象。 此外,还有一个未完全展示的方法`doc2XmlFile(Document document, String filename)`,它的...

    java操作word可操作书签

    Document doc = dBuilder.parse(docxFile.getInputStream(documentXML)); // 查找书签并替换 NodeList bookmarkStarts = doc.getElementsByTagName("w:bookmarkStart"); for (int i = 0; i < bookmarkStarts....

Global site tag (gtag.js) - Google Analytics