XML名称空间与DocumentBuilder / Transformer的不同实现不同

时间:2014-09-04 09:07:03

标签: java xml namespaces classloader

我有2台机器上有相同的java代码。代码是关于使用文档构建器构建xml文档,以及使用转换器将该文档转换为字符串。两者都使用factory.newInstance()实例化:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();

TransformerFactory tff = TransformerFactory.newInstance();
Transformer tf = tff.newTransformer();

然而,我注意到他们的表现不同。一台机器,在文档中插入节点正确地将空名称空间转换为名称空间,名称等于空字符串。在另一台机器上,这种情况不会发生,并且没有插入命名空间,而且该元素使用父命名空间。

所以我比较了工厂和建造者/变压器的实际类/类加载器,它们确实不同。这是正确输出的日志文件:

DocumentBuilderFactory class name:      com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl
DocumentBuilderFactory class loader:        null
DocumentBuilderFactory class package:       package com.sun.org.apache.xerces.internal.jaxp, Java Platform API Specification, version 1.7

DocumentBuilder class name:             com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl
DocumentBuilder class loader:           null
DocumentBuilder class package:      package com.sun.org.apache.xerces.internal.jaxp, Java Platform API Specification, version 1.7

TransformerFactory class name:      com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl
TransformerFactory class loader:        null
transformerFactory class package:       package com.sun.org.apache.xalan.internal.xsltc.trax, Java Platform API Specification, version 1.7

Transformer class name:             com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl
Transformer class loader:           null
Transformer class package:          package com.sun.org.apache.xerces.internal.jaxp, Java Platform API Specification, version 1.7

这里是WRONG输出的日志:

DocumentBuilderFactory class name:      org.apache.xerces.jaxp.DocumentBuilderFactoryImpl
DocumentBuilderFactory class loader:        sun.misc.Launcher$AppClassLoader@2ff40e1f
DocumentBuilderFactory class package:       package org.apache.xerces.jaxp

DocumentBuilder class name:             org.apache.xerces.jaxp.DocumentBuilderImpl
DocumentBuilder class loader:           sun.misc.Launcher$AppClassLoader@2ff40e1f
DocumentBuilder class package:      package org.apache.xerces.jaxp

TransformerFactory class name:      org.apache.xalan.processor.TransformerFactoryImpl
TransformerFactory class loader:        sun.misc.Launcher$AppClassLoader@2ff40e1f
transformerFactory class package:       package org.apache.xalan.processor

Transformer class name:             org.apache.xalan.transformer.TransformerIdentityImpl
Transformer class loader:           sun.misc.Launcher$AppClassLoader@2ff40e1f
Transformer class package:          package org.apache.xerces.jaxp

我想告诉第二台机器的行为与第一台机器相似,但我不熟悉cloassloader的工作方式。任何人都可以给我详细信息:

1)为什么会出现差异,在这种情况下,类加载意味着什么? 2)如何更改机器#2的默认行为以使用与机器#1相同的东西?

1 个答案:

答案 0 :(得分:1)

这可能是错误的方式。 Apache中的Xerces和Xalan版本通常比JDK中的版本更可靠,更健壮,标准更符合标准。我会尝试将所有内容移动到Apache版本,并弄清楚为什么你的代码在这些情况下给出了错误的结果,并修复它。我们需要仔细查看您认为哪些代码会给出错误结果的详细信息,以告诉您哪个产品实际上是根据规范行事,哪个不是。根据规范选择正确的产品比选择合适的产品要好得多。

您可以通过多种方式控制JAXP加载的版本:通过更改类路径上的内容,设置Java系统属性或显式加载所选版本。如果你看一下像DocumentBuilderFactory和TransformerFactory这样的类的Javadoc,它会给你一个非常详细的解释。

相关问题