当前位置: 首页 > 知识库问答 >
问题:

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

赫连卓
2023-03-14

我即将更新我们项目的依赖项,发现 docx4j 已更改其类 FlatOpcXml 创建器的接口。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中。
  • V11.3.2是V8.3.2的Java11的分支
  • 我们之前用的是V11.2.9。
  • 我切换到V11.3.2时出错。

V8.3.0的发布消息提到FlatOpcXmlCreator中的更改是由于以下问题:https://github.com/plutext/docx4j/issues/444.我简短地看了一下讨论,但找不到任何有关我的问题的有用信息。

编辑:在我的示例中,worker.get() 被用作获取文档的 dom 表示形式的快捷方式。因为这有点笨拙(这不是FlatOpcXml创建者公开其内部结构的范围),当前版本的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()));

共有1个答案

洪英豪
2023-03-14

有关现在该做什么的示例,请参见https://github . com/plutext/docx4j/blob/master/docx4j-core/src/main/Java/org/docx4j/open packaging/packages/OPC package . Java # L735

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

给定你的wordPackage,只需wordPackage.save(outStream,Docx4J.FLAG_SAVE_FLAT_XML)

 类似资料:
  • 问题内容: 标记界面没有任何东西。它仅包含接口声明,然后JVM如何对实现此标记接口的类进行处理? 我们可以创建任何新的标记器接口吗? 问题答案: 您的问题确实应该是 编译器 如何处理标记接口,而答案是: 与其他接口没有什么不同 。例如,假设我声明了一个新的标记接口: …然后声明一个实现的类: 我现在可以通过type的引用来引用的实例: …,并(在运行时)检查对象是否实现: 后一种情况通常是使用标记

  • 问题内容: 据我所知,我们无法实例化接口,那么这是怎么发生的呢? 问题答案: 您无法实例化接口,但是可以为实现该接口的类的对象提供接口的引用,因此在代码中,您正在实现接口并创建该类的对象并提供该类的引用。

  • 假设我有注释类: 如何从它扩展接口?编译器在这方面失败: 游乐场链接:https://www.typescriptlang.org/play/#src=const匿名类=类{} let a: typeof匿名类; 接口I扩展类型的匿名类{

  • 问题内容: 例如, 我正在尝试使用运行时反射获取列表。 问题答案: 试试这个: 游乐场的例子 获取接口类型的reflect.Type是棘手的部分。请参阅如何获取接口的reflect.Type?进行解释。

  • 我想得到由接口实现的子类名。例如 在我的代码中,我声明了接口A,并将值设置为其中一个类。所以我有这样的: 现在我想得到当前的子类名称,比如B、C或其他什么,但我不想用instanceof,因为我有很多子类,这使得代码不必要太长。我基本上是在寻找这个,但是getChild()当然不存在。 提前谢谢!

  • 我有这个界面: 我需要一个类来实现它,但我无法获得在类中实现getDist()方法的正确语法。。 它说: 类'Point'声明接口'IPoint'但不实现它:类型'Point'和'IPoint'的属性'getDist'的类型不兼容:调用类型'()= 做这件事的正确方法是什么? 谢谢