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?
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>
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.
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.
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With