Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

java

xml

jaxb

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>
like image 613
mike Avatar asked Feb 16 '16 22:02

mike


People also ask

How does JAXB marshalling work?

In JAXB, marshalling involves parsing an XML content object tree and writing out an XML document that is an accurate representation of the original XML document, and is valid with respect the source schema. JAXB can marshal XML data to XML documents, SAX content handlers, and DOM nodes.

What is marshalling and Unmarshalling in Java example?

Marshalling is the process of transforming Java objects into XML documents. Unmarshalling is the process of reading XML documents into Java objects. The JAXBContext class provides the client's entry point to the JAXB API. It provides API for marshalling, unmarshalling and validating.


1 Answers

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>
like image 69
Michael Glavassevich Avatar answered Sep 20 '22 18:09

Michael Glavassevich