How would I marshal a List of Jaxb Elements without making a wrapper class?

jaxb list of elements
jaxb unmarshal list of objects
jaxb unmarshal returns null values for elements
jaxb multiple root elements
unmarshalling soap response to java object example
unmarshal soap message (xml) to java object using jaxb
how to unmarshal complex xml using jaxb
xmlelementwrapper

Short of actually making up a writer and appending each element onto the string. Is there a way to get the JAXB marshaller to marshall a list of objects where I can just give it the name of the top element?

I feel like I'm close with this

//http://blog.bdoughan.com/2012/07/jaxb-no-annotations-required.html
public <T> String jaxb(Collection<T> o, Class<T> clazz, String plural){
    try {
        ArrayList<T> al = new ArrayList<T>(o.size());
        al.addAll(o);
        JAXBContext jc = JAXBContext.newInstance(ArrayList.class);
        JAXBElement<ArrayList> amenity = new JAXBElement(new QName(plural), ArrayList.class, al);
        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        StringWriter writer = new StringWriter();
        marshaller.marshal(amenity, writer);
        return writer.toString();
    } catch (JAXBException e) {
        throw new RuntimeException(e);
    }
}

but the result is still coming back as an empty list

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<pluralName/>

Is there a way to do this without just manually pasting strings of xml together?

Update

With some help from Michael Glavassevich I've been able to do this with one caveat, the individual elements are <Item>s

//http://blog.bdoughan.com/2012/07/jaxb-no-annotations-required.html
@SuppressWarnings({ "unchecked", "rawtypes" })
public <T> String jaxb(Collection<T> elements, Class<T> elementClass, String plural){
    try {
        T[] array = (T[]) Array.newInstance(elementClass, elements.size());
        elements.toArray(array);
        JAXBContext jc = JAXBContext.newInstance(array.getClass());
        JAXBElement<T[]> topElement = new JAXBElement(new QName(plural), array.getClass(), array);
        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        StringWriter writer = new StringWriter();
        marshaller.marshal(topElement, writer);
        return writer.toString();
    } catch (JAXBException e) {
        throw new RuntimeException(e);
    }
}

The result then becomes

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Basketballs>
    <item>basketball one</item>
    <item>basketball two</item>
</Basketballs>

If you don't want to create a wrapper class you could convert the collection into an array, place that array in a JAXBElement and then marshal it.

For example:

public class JAXBArrayWriter {

    public static class Item {
        @XmlValue
        protected String value;

        public Item() {}

        public Item(String value) {
            this.value = value;
        }
    }

    public static void main (String [] args) throws Exception {
        List<Item> items = new ArrayList<Item>();
        items.add(new Item("one"));
        items.add(new Item("two"));
        JAXBContext jc = JAXBContext.newInstance(Item[].class);
        JAXBElement<Item[]> root = new JAXBElement<Item[]>(new QName("items"), 
                Item[].class, items.toArray(new Item[items.size()]));
        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        StringWriter writer = new StringWriter();
        marshaller.marshal(root, writer);
        System.out.println(writer.toString());
    }
}

which produces the following document:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<items>
    <item>one</item>
    <item>two</item>
</items>

JAXB, Java example of JAXB @XmlElementWrapper annotation in detail along with its usage during This annotation generates a wrapper element around XML representation. FIELD). public class Employee implements Serializable { private List<String> hobbies; Do not use @XmlElementWrapper (Unwrapped collection)  We know that JAXB(Java Architecture for XML Binding) allows Java developers to map Java classes to XML representations. JAXB provides two main features: the ability to marshal Java objects into XML and the inverse, i.e. to unmarshal XML back into Java objects. JAXB mostly is used while implementing webservices or any other such client interface …

Please try this:

First, create a list class:

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class AmenityList {
    @XmlElement(name = "amenity")
    List<Amenity> amenities = new ArrayList<Amenity>();

    public AmenityList() {}

    public void setList(List<Amenity> amenities) {
        this.amenities = amenities;
    }
}

then the Amenity class:

@XmlAccessorType(XmlAccessType.FIELD)
class Amenity {
    private String amenityName;
    private String amenityDate;

    public Amenity(String name, String date) {
        this.amenityName = name;
        this.amenityDate = date;
    }
}

set where needed your amenities in a list - maybe in a less redundant way :) - and assign it to an AmenityList:

AmenityList amenityList = new AmenityList();
List <Amenity> amenities = new ArrayList<Amenity>();
amenities.add(new Amenity("a_one", "today"));
amenities.add(new Amenity("a_two", "tomorrow"));
amenity.setList(amenities);

and finally, a toXml method:

public static String toXml(AmenityList amenityList) throws JAXBException {
    JAXBContext jaxbContext = JAXBContext.newInstance(AmenityList.class);
    Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
    jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
    StringWriter sw = new StringWriter();
    jaxbMarshaller.marshal(amenityList, sw);
    return sw.toString()
}

obtaining, i.e. :

<amenityList>
    <amenity>
        <amenityName>a_one</amenityName>
        <amenityDate>today</amenityDate>
    </amenity>
    <amenity>
        <amenityName>a_two</amenityName>
        <amenityDate>tomorrow</amenityDate>
    </amenity>
</amenityList>

JAXB @XmlElementWrapper Annotation Example, To marshal/unmarshal a list with a JAXB (JSR-222) implementation you need to We will create a generic wrapper class with a List property annotated with In the Address class we will use the default element names that JAXB Nice job Blaise, I am no expert in XML but was using it to store my test data  There are two ways to marshal those objects. First add jaxb.index file to the package containing the JAXB annotated classes and list them. The second way is to provide ObjectFactory in the package containing the JAXB annotated classes.

The accepted solution with array works but causes each inner element to be named : < item >

The following solution taken from this link worked better for me:

Is it possible to programmatically configure JAXB?

public class Wrapper<T> {

private List<T> items = new ArrayList<T>();

@XmlAnyElement(lax=true)
public List<T> getItems() {
    return items;
}

}

//JAXBContext is thread safe and so create it in constructor or 
//setter or wherever:
... 
JAXBContext jc = JAXBContext.newInstance(Wrapper.class, clazz);
... 

public String marshal(List<T> things, Class clazz) {

  //configure JAXB and marshaller     
  Marshaller m = jc.createMarshaller();
  m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

  //Create wrapper based on generic list of objects
  Wrapper<T> wrapper = new Wrapper<T>(things);
  JAXBElement<Wrapper> wrapperJAXBElement = new JAXBElement<Wrapper>(new QName(clazz.getSimpleName().toLowerCase()+"s"), Wrapper.class, wrapper);

  StringWriter result = new StringWriter();
  //marshal!
  m.marshal(wrapperJAXBElement, result);

  return result.toString();

}

It does not require converting the list to an array, but does require 1 generic general purpose class.

Creating a Generic List Wrapper in JAXB, jaxb wrapper example for non-list elements. GitHub Gist: instantly XmlRootElement;. public class JaxbTest { TRUE );. marshaller.marshal(obj, System.out);. Creating a Generic List Wrapper in JAXB. To marshal/unmarshal a list with a JAXB (JSR-222) implementation you need to create a wrapper object to hold the list. People find this onerous having to create multiple wrapper objects for this purpose. Below I'll demonstrate that in reality you only need to create one. This post is based on an answer I gave on Stack Overflow.

jaxb wrapper example for non-list elements · GitHub, When no name defined, the @XmlElementWrapper annotation uses the property List; @XmlRootElement public class Record { private Integer id; private String package org.kodejava.example.jaxb; import javax.xml.bind. try { writer = new FileWriter("Record.xml"); marshaller.marshal(record, writer); }  Java example of JAXB @XmlElementWrapper annotation in detail along with its usage during marshalling and unmarshalling operations. 1. @XmlElementWrapper Type. This annotation generates a wrapper element around XML representation. This is primarily intended to be used to produce a wrapper XML element around collections.

How to generate a wrapper element around XML representation in , In this example BookStore.java is the container class which contains list of Book.​java reference. XmLElementWrapper generates a wrapper element around XML Jha * */ public class BookMainApp { // create a doc folder if not available Write to File m.marshal(bookstore, new File(BOOKSTORE_XML));  jaxb wrapper example for non-list elements. GitHub Gist: instantly share code, notes, and snippets.

JAXB: Example of Nested List of XML Element, You will need a holder class (wrapper class). It will hold the arraylist that you want to marshall or unmarshall. Please see the self explanatory  One method is to wrap the instance as a value of a JAXBElement, and pass the wrapper element as the first parameter to a Marshaller.marshal method. For java to schema binding, it is also possible to simply annotate the instance's class with @ XmlRootElement .

Comments
  • This is step in the right direction, I'm having some trouble with one part though. Do you know how I would pass the class in to JAXBContext.newInstance() if I don't know the type? I apparently can't do JAXBContext.newInstance(T[].class)
  • actually never mind that i figured it out. I do have another problem though. If I change the Item class name to something like Basketball in your demo. The individual elements still come out as <item>. Any idea how to change this?
  • Seems to be related to the mapping rules for multidimensional arrays, equivalent to a schema type with <xs:element name="item" type=schematype minOccurs="0" maxOccurs="unbounded" nillable="true"/>. At least at the spec level this isn't configurable.
  • What are the changes needed in above method to generate JSON instead of XML
  • I don't know that the list of objects will be amenities, which is why I'm trying to to do it without a wrapper class.