codebreaker
codebreaker

Reputation: 813

Omit wrapper tags in JAXB when the collection is empty

In JAXB, you can use the @XmlElementWrapper attribute to specify tags to wrap a collection of elements. However, these wrapper tags appear even if the collection is empty (they don't appear if the collection is null). Is there any way to have JAXB omit the wrapper tags if the collection is empty? Using adapters on the collection doesn't seem to work, since JAXB interprets this to mean it should apply the adapter to each element in the collection.

Upvotes: 3

Views: 1937

Answers (2)

Thomas Fritsch
Thomas Fritsch

Reputation: 10147

You can enforce your desired behavior in a somewhat hackish way by using Marshal Event Callbacks.

@XmlRootElement(name="example")
@XmlAccessorType(XmlAccessType.FIELD)
public class Example {

    @XmlElementWrapper(name="wrapper")
    @XmlElement(name="item")
    private List<Item> items;

    // invoked by Marshaller before marshalling
    private void beforeMarshal(Marshaller marshaller) {
         if (items != null && items.isEmpty())
            items = null;
    }

    // ... getters and setters
}

As described in Marshal Event Callbacks there are actually 2 alternative ways how to use marshal callbacks:

  1. Put the beforeMarshal and/or afterMarshal method directly into your class, and that's it. (This is the simpler way, and that's why I used this in my answer).
  2. Create a Marshaller.Listener and write the beforeMarshal and afterMarshal methods there. You would then need to register this listener in your Marshaller.

Upvotes: 5

SomeDude
SomeDude

Reputation: 14238

You can use listener mechanism of Marshaller

You can add/set a listener like below :

jaxbMarshaller.setListener( new Listener()
{
    @Override
    public void beforeMarshal(Object source) 
    {
        if ( source instanceof MyCollectionWrapper )
        {
            MyCollectionWrapper wrapper = (MyCollectionWrapper)source;
            if ( wrapper.getCollection() != null && wrapper.getCollection().isEmpty() )
            {
                wrapper.setCollection( null );
            }
        }

    }
});

where MyCollectionWrapper is the class representing your wrapper class.

This should remove the wrapper tag when the collection is empty.

Upvotes: 1

Related Questions