使用JAXB将XML解组为现有对象

时间:2009-07-27 15:52:24

标签: java xml jaxb

我有一个xsd从一组现有的java类生成,目前它成功地将XML消息解组到对象中,但是我希望能够做的是我有一个现有的Object实例的地方unmarshaller只是更新传递给它的消息中包含的字段

例如

(原谅任何语法错误,只是在我的脑海中)

如果我有一个带有许多字段,标题,作者,已发布等的带注释的类书和相应的生成的xsd,那么设置为不需要的字段很多我希望能够获得以下xml

<Book>
 <title>Dummys guide to JAXB</title>
</Book>

而不是简单地创建仅包含标题集的新Book实例,将其应用于现有实例作为更新,因此只需在该实例上设置title变量。

3 个答案:

答案 0 :(得分:5)

JAXB无法为您做到这一点,不。但是,您可以使用JAXB将XML文档解组为新对象,然后将新对象的属性反射复制到现有对象上。

Commons BeanUtils为此提供了一种机制,例如BeanUtils.copyProperties方法。不过,我不确定这是不是很深刻。

答案 1 :(得分:0)

您可以使用JAXB进行此操作,但您必须自己完成大部分工作。

在您的示例中,您需要一个查找功能,例如用于预订对象的标题的单例注册表。

由于您的标识符title是子元素,因此无法保证JAXB将在任何其他元素之前访问title元素。最简单的方法是将Unmarshaller创建的Book实例中的属性复制到您的singleton Book实例。 afterUnmarsal回调是执行此操作的地方:

class Book {
 // ...
 private void afterUnmarshal(Unmarshaller reader, Object parent) { 
   Book singleton = BookRegistry.getInstance().getBook(this.title);
   if (this.publisher != null) singleton.setPublisher(this.publisher);
   if (this.author != null) singleton.setPublisher(this.publisher);
   // ...
 }
}

如果要动态注册XML文档中的对象,则会更复杂一些。在您的情况下,您可能需要以下内容:

class Book {
 // ...
 public void setTitle(String title) {
    this.title = title;
    Book singleton = BookRegistry.getInstance().getBook(this.title);
    if (singleton == null) BookRegistry.getInstance().addBook(this.title, this);
 }
}

只要您没有嵌套的图书就可以使用。

答案 2 :(得分:0)

您可以使用JAXB2 Commons - Copyable+plugin

中的可复制插件来实现此目的