使用 JAXB 解组对象进行克隆时如何保持 IDREF link?

How to keep IDREF link when unmarshalling an object with JAXB for cloning?

我用 XSD 模型定义了对象,我使用 Jaxb 创建相应的 classes,以便能够在 classes 的实例上加载 XML 文件,并且从 classes.

的实例生成 XML 文件

我在 XSD 模型上定义的元素很复杂,具有多个层级,使用列表、ID 和 IDREF。

我程序的一个命令是复制元素。

我无法使用克隆方法,因为 class 元素是由 JAXB 生成的。 所以我尝试使用 BeanUtils.cloneBean 进行深度复制,然后使用 Apache 的 SerializationUtils.clone 进行深度复制,但是由于它们的复杂性,这两种方法都无法正确处理我的所有对象。

我找到了一个可行的解决方案,使用 JAXB 创建一个克隆解组我的元素:

public ObjectXML duplicate(ObjectXML objectXML) throws JAXBException {

  JAXBContext sourceJaxbContext = JAXBContext.newInstance(objectXML.getClass());
  JAXBContext targetJaxbContext = JAXBContext.newInstance(objectXML.getClass());

  Unmarshaller unmarshaller = targetJaxbContext.createUnmarshaller();

  ObjectXML objectCopy = (ObjectXML) unmarshaller.unmarshal(new JAXBSource(sourceJaxbContext, objectXML));

  return objectCopy;
}

ObjectXML 是 JAXB 生成的所有元素的父对象 class。所有元素直接或间接继承自此 class.

此方法工作正常,但 IDREF 属性 link 到另一个对象除外:当我解组单个对象时,JAXB 不知道具有相应 ID 的元素,因此它将 null 分配给该属性。

当 linked 对象未提供给 JAXB 的解组时,是否有人提供了将 IDREF 保留在副本上的解决方案?

谢谢你的提前。

一些提示。

  • 试试 copyable plugin from JAXB2-Basics。该插件生成深度无反射复制方法,可以很好地处理 JAXB 结构,您还可以指定自己的复制策略。 免责声明:我是作者。
  • 实施并注册您自己的 IDResolver,请参阅 this blog post。这将允许您插入自己的 ID 解析策略。