我已经尝试了此处作为答案提供的所有解决方案,但没有一个适用于我的环境。我目前的要求是:
- jdk1.6.0_45
- 每次重建时都会生成 JAXB 注释类,因此
更改它们不是一种选择。
我想与您分享我在 stackoverflow 上找到的解决方案的实验结果。
自定义命名空间上下文 link
简单而优雅的解决方案,但在我的环境中,我有以下堆栈跟踪的异常:
javax.xml.stream.XMLStreamException: Trying to write END_DOCUMENT when document has no root (ie. trying to output empty document).
at com.ctc.wstx.sw.BaseStreamWriter.throwOutputError(BaseStreamWriter.java:1473)
at com.ctc.wstx.sw.BaseStreamWriter.reportNwfStructure(BaseStreamWriter.java:1502)
at com.ctc.wstx.sw.BaseStreamWriter.finishDocument(BaseStreamWriter.java:1663)
at com.ctc.wstx.sw.BaseStreamWriter.close(BaseStreamWriter.java:288)
at MyDataConverter.marshal(MyDataConverter.java:53)
我在试图弄清楚为什么会发生此异常时陷入困境,并决定尝试其他方法。
package-info.java的修改 link
我找到的最简单的解决方案。它通常可以工作,但是这个文件是在每次构建时生成的。这就是为什么我必须找到另一个解决方案。
架构修改 link
按描述工作,但不能解决我的问题。我在根元素中仍然有一个命名空间。
委托XMLStreamWriter link
我也尝试过那里提到的解决方案,但我在 com.sun.xml.bind.v2.runtime.output.NamespaceContextImpl(方法 declareNsUri)中有一个奇怪的断言,但我未能击败。
我的解决方案
在研究断言问题时,我必须基于 DelegatingXMLStreamWriter.java 实现我自己的 XMLStreamWriter 版本
public class NamespaceStrippingXMLStreamWriter extends DelegatingXMLStreamWriter {
public NamespaceStrippingXMLStreamWriter(XMLStreamWriter xmlWriter) throws XMLStreamException {
super(xmlWriter);
}
@Override
public void writeNamespace(String prefix, String uri) throws XMLStreamException {
// intentionally doing nothing
}
@Override
public void writeDefaultNamespace(String uri) throws XMLStreamException {
// intentionally doing nothing
}
@Override
public void writeStartElement(String prefix, String local, String uri) throws XMLStreamException {
super.writeStartElement(null, local, null);
}
@Override
public void writeStartElement(String uri, String local) throws XMLStreamException {
super.writeStartElement(null, local);
}
@Override
public void writeEmptyElement(String uri, String local) throws XMLStreamException {
super.writeEmptyElement(null, local);
}
@Override
public void writeEmptyElement(String prefix, String local, String uri) throws XMLStreamException {
super.writeEmptyElement(null, local, null);
}
@Override
public void writeAttribute(String prefix, String uri, String local, String value) throws XMLStreamException {
super.writeAttribute(null, null, local, value);
}
@Override
public void writeAttribute(String uri, String local, String value) throws XMLStreamException {
super.writeAttribute(null, local, value);
}
}
主要思想是避免将命名空间信息传递给底层的 XMLStreamWriter。希望这将帮助您节省一些时间来解决类似的问题。
PS。没有必要在您的代码中扩展 DelegatingXMLStreamWriter。我这样做是为了说明哪些方法需要更改。