如何处理 V11.3.2(又名 V8.3.0)中 docx4j Class "FlatOpcXmlCreator" 接口的重大变化

How to Handle Breaking Change in Interface of docx4j Class "FlatOpcXmlCreator" in V11.3.2 (aka V8.3.0)

我正要更新我们项目的依赖项,发现 docx4j 已经更改了它的 class FlatOpcXmlCreator 接口。 get() 方法现在不仅已弃用,而且已完全停用,如以下 docx4j 代码片段所示:

package org.docx4j.convert.out.flatOpcXml;
public class FlatOpcXmlCreator implements Output {
...
@Deprecated
public Package get() throws Docx4JException {
    throw new Docx4JException("Deprecated.");
}

(恕我直言,我认为他们在这里只是跳过了通常已弃用的步骤,即仍然支持该功能,给出警告并记录如何升级到新界面的提示)。无论如何,现在下面的代码不再起作用(因为最后一行调用了已弃用的 get() 方法)。

JAXBContext jc = Context.jcXmlPackage;
Marshaller marshaller = jc.createMarshaller();
org.w3c.dom.Document doc = XmlUtils.neww3cDomDocument();

FlatOpcXmlCreator worker = new FlatOpcXmlCreator(wordPackage);
marshaller.marshal(worker.get(), doc);

有人知道怎么解决吗?我查看了发布消息。这里提到了变化,但没有更多细节: https://www.docx4java.org/forums/announces/docx4j-8-3-0-released-t2992.html

只是我尝试过的实际版本切换的一些细节(因为这里的版本控制并不完全显而易见):

V8.3.0的发布消息提到FlatOpcXmlCreator的变化是由于以下问题:https://github.com/plutext/docx4j/issues/444。我快速浏览了讨论,但找不到任何关于我的问题的有用信息。


编辑:在我的示例中,worker.get() 被用作获取文档的 dom 表示形式的快捷方式。因为这有点 hacky(暴露它的内部结构不是 FlatOpcXmlCreator 的范围)当前版本的 docx4j 不能满足我们的需求。一个解决方案是应用 Jason 的解决方案并自己解析字符串。


解决方案:遵循 JasonPlutext 的建议(尤其是来自评论部分的建议)导致了以下修复:

FlatOpcXmlCreator worker = new FlatOpcXmlCreator(wordPackage);
worker.populate();

var outputStream = new ByteArrayOutputStream();
worker.marshal(outputStream);
org.w3c.dom.Document doc = XmlUtils.getNewDocumentBuilder().parse(
    new ByteArrayInputStream(outputStream.toByteArray()));

有关现在要做什么的示例,请参阅 https://github.com/plutext/docx4j/blob/master/docx4j-core/src/main/java/org/docx4j/openpackaging/packages/OpcPackage.java#L735

        FlatOpcXmlCreator opcXmlCreator = new FlatOpcXmlCreator(this);
        opcXmlCreator.populate();
        opcXmlCreator.marshal(outStream);

鉴于您的 wordPackage,只需 wordPackage.save(outStream, Docx4J.FLAG_SAVE_FLAT_XML)