简体   繁体   English

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

[英]Unmarshalling XML to existing object using JAXB

I have an xsd generated from a set of existing java classes and currently it successfully unmarshalls XML messages into the object as expected, however what I'd like the ability to do is where I have an existing instance of the Object have the unmarshaller simply update the fields that are contained within the message passed to it 我有一个从一组现有的java类生成的xsd,目前它成功地将XML消息解组到对象中,但是我希望能够做的是我有一个现有的Object实例,只需更新unmarshaller传递给它的消息中包含的字段

for example (forgive any syntax errors here its just off the top of my head) 例如(原谅任何语法错误,它只是在我的头顶)

If I had an annotated class Book with numerous fields, title, author, published etc and corresponding generated xsd, alot of the fields set to being not required I'd like to be able if I received the following xml 如果我有一个带有许多字段,标题,作者,已发布等的带注释的类Book和相应的生成的xsd,那么设置为不需要的字段很多,如果我收到以下xml,我希望能够

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

rather than simply create an new Book instance with only the title set apply this to an existing instance as an update, so simply setting the title variable on that instance. 而不是简单地创建仅具有标题集的新Book实例,将其应用于现有实例作为更新,因此只需在该实例上设置title变量。

JAXB can't do that for you, no. JAXB无法为您做到这一点,不。 However, what you could do is use JAXB to unmarshal your XML document on to a new object, and then reflectively copy the properties of the new object on to your existing one. 但是,您可以使用JAXB将XML文档解组为新对象,然后将新对象的属性反射复制到现有对象上。

Commons BeanUtils provides a mechanism for this, such as the BeanUtils.copyProperties method. Commons BeanUtils为此提供了一种机制,例如BeanUtils.copyProperties方法。 I'm not sure if this does deep-copies, though. 不过,我不确定这是否有深度拷贝。

You make this work with JAXB, but you have to do most of the work yourself. 您可以使用JAXB进行此操作,但您必须自己完成大部分工作。

In your example you need a look up capability, like a singleton registry of titles to book objects. 在您的示例中,您需要一个查找功能,例如用于预订对象的标题的单例注册表。

Since your identifier, title, is a child element, there is no guarantee that JAXB will visit the title element before any other element. 由于您的标识符title是子元素,因此无法保证JAXB将在任何其他元素之前访问title元素。 The easiest way around this is to just copy properties from the Book instance created by the Unmarshaller to your singleton Book instance. 最简单的方法是将Unmarshaller创建的Book实例中的属性复制到您的singleton Book实例。 The afterUnmarsal callback is the place to do this: 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);
   // ...
 }
}

If you want to register objects out of the XML document on the fly, it is a little more complex. 如果要动态注册XML文档中的对象,则会更复杂一些。 In your case, you probably want something like: 在你的情况下,你可能想要这样的东西:

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);
 }
}

which will work as long as you don't have nested Books. 只要你没有嵌套的书籍,这将有效。

您可以使用JAXB2 Commons的 Copyable插件 - 可复制 +插件来实现此目的

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM