mortenoh
mortenoh

Reputation: 255

Marshalling collections when using XmlElementWrapper

I have a collection on my class that uses @XmlElementWrapper to wrap the collection in a extra element.

So, my class looks something like this:

class A {
  @XmlElement(name = "bee")
  @XmlElementWrapper
  public List<B> bees;
}

And my XML then looks something like:

<a>
  <bees>
    <bee>...</bee>
    <bee>...</bee>
  </bees>
</a>

Great, this is what I wanted. However, when I try and marshall into JSON, I get this:

{
  "bees": {
    "bee": [
      ....
    ]
  }
}

And I don't want that extra "bee" key there.

Is it possible to somehow have MOXy ignore the XmlElement part when doing this marshalling? because I still need the name to be "bees" and not "bee", and I don't want both.

I'm using MOXy 2.4.1 and javax.persistence 2.0.0.

Upvotes: 2

Views: 1960

Answers (1)

bdoughan
bdoughan

Reputation: 149047

Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.

oxm.xml

You could use MOXy's external mapping document to provide an alternate mapping for your JSON-binding (see: http://blog.bdoughan.com/2010/12/extending-jaxb-representing-annotations.html).

<?xml version="1.0"?>
<xml-bindings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
    package-name="forum14002508">
    <java-types>
        <java-type name="A">
            <java-attributes>
                <xml-element java-attribute="bees" />
            </java-attributes>
        </java-type>
    </java-types>
</xml-bindings>

Demo

In the demo code below we will create two instances of JAXBContext. The first is build solely on the JAXB annotations that we will use for XML. The second is built on the JAXB annotations and uses MOXy's external mapping file to override the mapping for the bees property on the A class.

package forum14002508;

import java.util.*;
import javax.xml.bind.*;

import org.eclipse.persistence.jaxb.JAXBContextProperties;

public class Demo {

    public static void main(String[] args) throws Exception {

        List<B> bees = new ArrayList<B>();
        bees.add(new B());
        bees.add(new B());
        A a = new A();
        a.bees = bees;

        JAXBContext jc1 = JAXBContext.newInstance(A.class);
        Marshaller marshaller1 = jc1.createMarshaller();
        marshaller1.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller1.marshal(a, System.out);

        Map<String, Object> properties = new HashMap<String, Object>(3);
        properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, "forum14002508/oxm.xml");
        properties.put(JAXBContextProperties.MEDIA_TYPE, "application/json");
        properties.put(JAXBContextProperties.JSON_INCLUDE_ROOT, false);
        JAXBContext jc2 = JAXBContext.newInstance(new Class[] {A.class}, properties);
        Marshaller marshaller2 = jc2.createMarshaller();
        marshaller2.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller2.marshal(a, System.out);
    }

}

Output

Below is the output from running the demo code that matches your use case.

<a>
   <bees>
      <bee/>
      <bee/>
   </bees>
</a>
{
   "bees" : [ {
   }, {
   } ]
}

For More Information

Upvotes: 2

Related Questions