简体   繁体   中英

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

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>
 <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.

JAXB can't do that for you, no. 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.

Commons BeanUtils provides a mechanism for this, such as the BeanUtils.copyProperties method. 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.

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. The easiest way around this is to just copy properties from the Book instance created by the Unmarshaller to your singleton Book instance. The afterUnmarsal callback is the place to do this:

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. 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插件 - 可复制 +插件来实现此目的

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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