Creating multiple XML files from a hashmap in Java - java

I'm trying to create a XML file from a HashMap. For each key of the hash i want an XML file. The value of the key is an ArrayList of Objects. I am using JAXB but the XML files are not created, as the output is not XML valid.
The object class:
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name = "Product")
public class Product implements Comparable<Product>{
String ID,description, gtin;
double price;
String date;
Product()
{
}
public String toString()
{
return ID+" "+description+" "+gtin+" "+price+" "+date;
}
public String getID() {
return ID;
}
#XmlElement
public void setID(String ID) {
this.ID = ID;
}
public String getDescription() {
return description;
}
#XmlElement
public void setDescription(String description) {
this.description = description;
}
public String getGtin() {
return gtin;
}
#XmlElement
public void setGtin(String gtin) {
this.gtin = gtin;
}
public double getPrice() {
return price;
}
#XmlElement
public void setPrice(Double price) {
this.price = price;
}
}
The class where i try to create the XMLs:
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
public class CreateXML {
static void create(HashMap<String, ArrayList<Product> > map) {
try {
JAXBContext jaxbContext = JAXBContext.newInstance(ProdsList.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
Set setOfKeys = map.keySet();
Iterator iterator = setOfKeys.iterator();
while (iterator.hasNext()) {
String keys = (String) iterator.next();
String filename= "C:\\Users\\As\\Desktop\\Sups\\"+keys+22+".xml";
File file = new File(filename);
ArrayList<Product> value = map.get(keys);
jaxbMarshaller.marshal(value, file);
jaxbMarshaller.marshal(value, System.out);
}
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
The class for the root of the xml:
import java.util.*;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSeeAlso;
//#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement(name="Products")
//#XmlSeeAlso({ArrayList.class})
class ProdsList {
#XmlElement(name="Product")
ArrayList<Product> prods;
public ProdsList(){
prods=new ArrayList<Product>();
}
public ArrayList<Product> getProducts() {
return prods;
}
public void setProducts(ArrayList<Product> prods) {
this.prods = prods;
}
}
How can i fix this. Thanks in advance.

You need to marshal an instance of ProdsList. Instead you are trying to marshall
an ArrayList of Products.
Change
jaxbMarshaller.marshal(value, file);
jaxbMarshaller.marshal(value, System.out);
To
jaxbMarshaller.marshal(new ProdsList(value), file);
jaxbMarshaller.marshal(new ProdsList(value), System.out);

Related

jackson List of subclasses deserialisation

I am working on a webservice where i am supposed to provide xml as response, I am using jackson for that. I am stuck at an issue, I have an abstract class:
package com.spinner.jackson;
import java.util.ArrayList;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonUnwrapped;
import com.fasterxml.jackson.annotation.JsonValue;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlText;
public class ClientObject {
#JacksonXmlElementWrapper(useWrapping = false)
#JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT)
private List<MyItem> accounts;
public ClientObject(List<MyItem> pl) {
this.accounts = pl;
}
public ClientObject() {
this.accounts = new ArrayList<MyItem>();
}
#JsonDeserialize(using = CustomDeserial.class)
public void setL(List<MyItem> l) {
this.accounts = l;
}
public List<MyItem> getAccounts() {
// TODO Auto-generated method stub
return this.accounts;
}
}
and then I have sub classes as follow:
package com.spinner.jackson;
import javax.xml.bind.annotation.XmlRootElement;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
#JacksonXmlRootElement(localName="itemA")
public class MySubItemA extends MyItem {
public MySubItemA() {
super();
// TODO Auto-generated constructor stub
}
public MySubItemA(int id, String name) {
super(id, name);
// TODO Auto-generated constructor stub
}
private String itemAProperty1;
private String itemAProperty2;
public String getItemAProperty1() {
return this.itemAProperty1;
}
public void setItemAProperty1(String itemAProperty1) {
this.itemAProperty1 = itemAProperty1;
}
public String getItemAProperty2() {
return this.itemAProperty2;
}
public void setItemAProperty2(String itemAProperty2) {
this.itemAProperty2 = itemAProperty2;
}
#JsonCreator
public MySubItemA(#JsonProperty("id")int id, #JsonProperty("name")String name, #JsonProperty("itemAProperty1")String p1, #JsonProperty("itemAProperty2")String p2) {
super(id, name);
this.itemAProperty1 = p1;
this.itemAProperty2 = p2;
}
}
another sub class
package com.spinner.jackson;
import javax.xml.bind.annotation.XmlRootElement;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
#JacksonXmlRootElement(localName="itemB")
public class MySubItemB extends MyItem {
private int itemBProperty1;
private String itemBProperty2;
public int getItemBProperty1() {
return this.itemBProperty1;
}
public void setItemBProperty1(int itemBProperty1) {
this.itemBProperty1 = itemBProperty1;
}
public String getItemBProperty2() {
return this.itemBProperty2;
}
public void setItemBProperty2(String itemBProperty2) {
this.itemBProperty2 = itemBProperty2;
}
public MySubItemB(#JsonProperty("id")int id, #JsonProperty("name")String name, #JsonProperty("itemBProperty1")int p1, #JsonProperty("itemBProperty2")String p2) {
super(id, name);
this.itemBProperty1 = p1;
this.itemBProperty2 = p2;
}
}
and a client class as followed:
package com.spinner.jackson;
import java.util.ArrayList;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonUnwrapped;
import com.fasterxml.jackson.annotation.JsonValue;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlText;
public class ClientObject {
#JacksonXmlElementWrapper(useWrapping = false)
#JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT)
private List<MyItem> accounts;
public ClientObject(List<MyItem> pl) {
this.accounts = pl;
}
public ClientObject() {
this.accounts = new ArrayList<MyItem>();
}
#JsonDeserialize(using = CustomDeserial.class)
public void setL(List<MyItem> l) {
this.accounts = l;
}
#JsonDeserialize(using = CustomDeserial.class)
public List<MyItem> getAccounts() {
// TODO Auto-generated method stub
return this.accounts;
}
}
MyItem Class:
package com.spinner.jackson;
import javax.xml.bind.annotation.XmlRootElement;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonSubTypes.Type;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
#XmlRootElement
public abstract class MyItem {
public MyItem() {
super();
// TODO Auto-generated constructor stub
}
private int id;
private String name;
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public MyItem(int id, String name) {
this.id = id;
this.name = name;
}
}
above generate output xml as followed
<ClientObject>
<accounts>
<MySubItemA>
....
</MySubItemA>
</accounts>
<accounts>
<MySubItemB>
....
</MySubItemB>
</accounts>
</ClientObject>
is there a way to remove <accounts> wrapper even though I am using #JacksonXmlElementWrapper(useWrapping = false), also if I remove this annotation it does something as followed
<ClientObject>
<accounts>
<accounts>
<MySubItemA>
....
</MySubItemA>
</accounts>
<accounts>
<MySubItemB>
.....
</MySubItemB>
</accounts>
</accounts>
</ClientObject>
so final output should be
<ClientObject>
<MySubItemA>
....
</MySubItemA>
<MySubItemB>
....
</MySubItemB>
</ClientObject>
thanks for your help.
Best regards
Sajid
I was able to figure it out so I think it may help someone else:
I created Serializer
package com.spinner.jackson;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
public class MySerial extends JsonSerializer<ClientObject>
{
public void serialize(ClientObject value, JsonGenerator jgen,
SerializerProvider provider)
throws IOException, JsonProcessingException
{
jgen.writeObjectFieldStart(value.getClass().getSimpleName());
jgen.writeObjectField(value.getAccounts().get(0).getClass().getSimpleName(), value.getAccounts().get(0));
jgen.writeObjectField(value.getAccounts().get(1).getClass().getSimpleName(), value.getAccounts().get(1));
jgen.writeObjectField(value.getAccounts().get(2).getClass().getSimpleName(), value.getAccounts().get(2));
jgen.writeObjectField(value.getAccounts().get(3).getClass().getSimpleName(), value.getAccounts().get(3));
}
}
and next I did following in ClientObject.java:
package com.spinner.jackson;
import java.util.ArrayList;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
#JsonSerialize(using = CustomDeserial.class)
public class ClientObject {
#JacksonXmlElementWrapper(useWrapping = false)
#JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT)
private List<MyItem> accounts;
public ClientObject(List<MyItem> pl) {
this.accounts = pl;
}
public ClientObject() {
this.accounts = new ArrayList<MyItem>();
}
public void setL(List<MyItem> l) {
this.accounts = l;
}
public List<MyItem> getAccounts() {
return this.accounts;
}
}
and voila it worked, hope this helps some one.

JAXB unmarshalling elements with same name

this is my xml structure
<catalog>
<course>
<course_id></course_id>
<subjects>
<subject>
<subject_id></subject_id>
</subject>
<subject>
<subject_id></subject_id>
</subject>
</subjects>
</course>
</catalog>
So, i'v tried to bind this xml to a class using JAXB Unmarshalling, but the result was nothing.
I was thinking, i have 2 base elements, course and subject, so i built 2 classes based on these elements.
This to control the course tag
#XmlRootElement(name="catalog")
#XmlAccessorType(XmlAccessType.FIELD)
public class curso {
#XmlElement(name="course_id")
int course_id;
#XmlElementWrapper(name="subjects")
#XmlElement(name="subject")
List <subject> subjects = new ArrayList<>();
public void setCourse_id(int curso_id) {
this.curso_id = curso_id;
}
public void setSubjects(List<subject> subjects) {
this.subjects = subjects;
}
}
And This to control the subject tag.
public class subject {
String subject_id;
#XmlElement(name="subject_id")
public void setSubjectId(String id) {
this.subject_id = id;
}
}
I made some to string functions, and my output was nothing.
What is the problem?
The course element also have a wrapper tag <course> So either you need to change you xml to remove <catalog> tag and make <course> as the root. Or you should create a new class catalog and make course as a field. Like
#XmlRootElement(name="catalog")
#XmlAccessorType(XmlAccessType.FIELD)
class catalog {
#XmlElement(name="course")
curso course;
public curso getCourse() {
return course;
}
public void setCourse(curso course) {
this.course = course;
}
#Override
public String toString() {
return "catalog [course=" + course + "]";
}
}
A complete example
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name="catalog")
#XmlAccessorType(XmlAccessType.FIELD)
class catalog {
#XmlElement(name="course")
curso course;
public curso getCourse() {
return course;
}
public void setCourse(curso course) {
this.course = course;
}
#Override
public String toString() {
return "catalog [course=" + course + "]";
}
}
class curso {
#XmlElement(name = "course_id")
int course_id;
#XmlElementWrapper(name = "subjects")
#XmlElement(name = "subject")
List<subject> subjects = new ArrayList<>();
public void setCourse_id(int curso_id) {
this.course_id = curso_id;
}
public void setSubjects(List<subject> subjects) {
this.subjects = subjects;
}
#Override
public String toString() {
return "curso [course_id=" + course_id + ", subjects=" + subjects + "]";
}
}
class subject {
String subject_id;
#XmlElement(name = "subject_id")
public void setSubjectId(String id) {
this.subject_id = id;
}
#Override
public String toString() {
return "subject [subject_id=" + subject_id + "]";
}
}
public class JaxbExample2 {
public static void main(String[] args) {
try {
File file = new File("file.xml");
JAXBContext jaxbContext = JAXBContext.newInstance(catalog.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
catalog customer = (catalog) jaxbUnmarshaller.unmarshal(file);
System.out.println(customer);
} catch (JAXBException e) {
e.printStackTrace();
}
}
}

Converting JSON object to string in JAXB

Am writing an Webservice endpoint which will produce JSON and XML response. Here i would like to convert an object to JSON and setting it to string. When i try to do with the below code
Webservice Endpoint
package com.test1;
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;`
#Path("v1")
public class Impl1 {
#POST
#Path("method")
#Produces({"text/xml","application/json"})
public XML method() throws JSONException
{
//JSONObject obj = new JSONObject();
JSONArray ary = new JSONArray();
Main main = new Main();`
List<Student> details = new ArrayList<Student>() ;
Student s1 = new Student();
Student s2 = new Student();
Student s3 = new Student();
s1.setId("ID1");
s1.setValue("1");
s2.setId("ID2");
s2.setValue("2");
s3.setId("ID3");
s3.setValue("3");
details.add(s1);
details.add(s2);
details.add(s3);
main.setDetails(details);
ary.put(details);
Employee emp = new Employee();
emp.setName("Mike");
emp.setSalary(1000);
XML xml = new XML();
xml.setDetails(ary.toString());
xml.setEmp(emp);
xml.setId("1");
return xml;
}
}
XML class (JAXB)
package com.test1;
import java.util.HashMap;
import java.util.Map;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
public class XML {
String id;
Employee emp;
String details;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Employee getEmp() {
return emp;
}
public void setEmp(Employee emp) {
this.emp = emp;
}
public String getDetails() {
return details;
}
public void setDetails(String details) {
this.details = details;
}
}
Student Class
package com.test1;
public class Student {
String id;
String Value;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getValue() {
return Value;
}
public void setValue(String value) {
Value = value;
Main Class
package com.test1;
import java.util.List;
public class Main {
List<Student> details;
public List<Student> getDetails() {
return details;
}
public void setDetails(List<Student> details) {
this.details = details;
}
}
So when i hit my service am getting response as
{
"details" : "[[{\"id\":\"ID1\",\"value\":\"1\"},{\"id\":\"ID2\",\"value\":\"2\"},{\"id\":\"ID3\",\"value\":\"3\"}]]",
"emp" : {
"name" : "Arun",
"salary" : "1000.0"
},
"id" : "1"
}
Expected String valuse as
[{"id":"ID1","value":"1"},{"id":"ID2","value":"2"},{"id":"ID3","value":"3"}]
My Question is Why JSONArray which was converted as String contains "\" on every key value pair. is there any way to overcome this?
Use Jackson or google-gson or any other library.
For example
http://howtodoinjava.com/2014/06/16/jackson-examples-convert-java-object-to-from-json/

JAXB Error: unexpected element when unmarshalling

Could someone help me understand why I'm getting this error:
javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"items"). Expected elements are <{}item>
I've new to JAX-B but been stuck on this all day, I really don't understand whats happening and any help is really appreciated, thanks a lot.
Item Class:
#XmlRootElement
public class Item {
private String itemID;
private String itemDescription;
//need to have a constructor with no params
public Item(){
}
//Constructor: sets object vars
public Item(String itemID, String itemDescription) {
this.itemID = itemID;
this.itemDescription = itemDescription;
}
#XmlAttribute
//getters and setters
public String getID() {
return itemID;
}
public void setId(String id) {
itemID= id;
}
#XmlElement
public String getDescription() {
return itemDescription;
}
public void setDescription(String description) {
itemDescription = description;
}
Unmarshalling code:
resource = client.resource("http://localhost:8080/testProject/rest/items");
ClientResponse response= resource.get(ClientResponse.class);
String entity = response.getEntity(String.class);
System.out.println(entity);
JAXBContext context = JAXBContext.newInstance(Item.class);
Unmarshaller um = context.createUnmarshaller();
Item item = (Item) um.unmarshal(new StringReader(entity));
And this is the XML i'm trying to parse:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<items>
<item id="1">
<description>Chinos</description>
</item>
<item id="2">
<description>Trousers</description>
</item>
</items>
Here is the Web Service that is creating the XML:
#GET
#Produces(MediaType.TEXT_XML)
public List<Item> getItemsBrowser(){
java.sql.Connection connection;
java.sql.Statement statement;
List<Item> items = new ArrayList<Item>();
ResultSet resultSet = null;
try {
connection = dataSource.getConnection();
statement = connection.createStatement();
String query = "SELECT * FROM ITEMS";
resultSet = statement.executeQuery(query);
// Fetch each row from the result set
while (resultSet.next()) {
String a = resultSet.getString("itemID");
String b = resultSet.getString("itemDescription");
//Assuming you have a user object
Item item = new Item(a, b);
items.add(item);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return items;
}
The class you're creating the JAXBContext from is Item.class, but the XML contains a list called items which in turn contains distinct item entries. You would need another class that wraps a
List<Item>
for this to work.
Here's a full working example:
The Items class:
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
public class Items {
private List<Item> items;
#XmlElement(name="item")
public List<Item> getItems() {
return items;
}
public void setItems(List<Item> items) {
this.items = items;
}
}
Note that there is an #XmlElement annotation on the items property, because the actual elements are called "item" in the XML.
The Item class:
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
public class Item {
private String itemID;
private String itemDescription;
// need to have a constructor with no params
public Item() {}
public Item(String itemID, String itemDescription) {
this.itemID = itemID;
this.itemDescription = itemDescription;
}
#XmlAttribute
public String getId() {
return itemID;
}
public void setId(String id) {
itemID = id;
}
#XmlElement
public String getDescription() {
return itemDescription;
}
public void setDescription(String description) {
itemDescription = description;
}
}
And a unit test:
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import org.junit.Test;
public class JAXBTest {
#Test
public void xmlIsUnmarshalled() throws JAXBException {
JAXBContext context = JAXBContext.newInstance(Items.class);
Unmarshaller um = context.createUnmarshaller();
Items items = (Items) um.unmarshal(new File("items.xml"));
assertNotNull(items);
assertNotNull(items.getItems());
assertEquals(2, items.getItems().size());
assertEquals("Chinos", items.getItems().get(0).getDescription());
assertEquals("Trousers", items.getItems().get(1).getDescription());
assertEquals("1", items.getItems().get(0).getId());
assertEquals("2", items.getItems().get(1).getId());
}
}
Since youa are using the Jersey cleint APIs you could do the following and avoid creating the Items class:
import java.util.List;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.GenericType;
import com.sun.jersey.api.client.WebResource;
public class JerseyClient {
public static void main(String[] args) {
Client client = Client.create();
WebResource resource = client.resource(""http://localhost:8080/testProject/rest/items"");
List<Item> items = resource.accept("application/xml").get(new GenericType<List<Item>>(){});
System.out.println(items.size());
}
}
For More Information
http://blog.bdoughan.com/2010/08/creating-restful-web-service-part-55.html

Generic Collections and XStream

Is there a way to map (using xstream) a List<Person> to <friends> and List<Things> to <stuff> for example?
Thanks!
Yes.
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
*
* #author nicholasdunn
*/
public class XStreamTest {
private List<Person> friends = new ArrayList<Person>();
private List<Thing> stuff = new ArrayList<Thing>();
public XStreamTest(List<Person> people, List<Thing> stuff) {
this.friends.addAll(people);
this.stuff.addAll(stuff);
}
private static class Person {
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
private static class Thing {
private String description;
public Thing(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
};
public static void main(String[] args) {
XStream xstream = new XStream(new DomDriver());
xstream.alias("test", XStreamTest.class);
xstream.alias("person", Person.class);
xstream.alias("thing", Thing.class);
XStreamTest test = new XStreamTest(Arrays.asList(new Person("Fred")), Arrays.asList(new Thing("Xbox 360")));
System.out.println(xstream.toXML(test));
}
}
Prints
<test>
<friends>
<person>
<name>Fred</name>
</person>
</friends>
<stuff>
<thing>
<description>Xbox 360</description>
</thing>
</stuff>
</test>
If you mean something else, please clarify the question.
Why not use JAXB instead? If you don't like the annotations you can use EclipseLink MOXy's XML metata representation:
import java.util.Arrays;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
public class JAXBTest {
#XmlRootElement
public static class Root {
private List<Person> friend;
private List<Thing> stuff;
#XmlElementWrapper(name="friends")
public List<Person> getFriend() {
return friend;
}
public void setFriend(List<Person> friend) {
this.friend = friend;
}
#XmlElementWrapper(name="stuff")
public List<Thing> getStuff() {
return stuff;
}
public void setStuff(List<Thing> stuff) {
this.stuff = stuff;
}
}
public static class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public static class Thing {
private String description;
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
public static void main(String[] args) throws JAXBException {
JAXBContext jaxbContext = JAXBContext.newInstance(Root.class);
Root root = new Root();
Person fred = new Person();
fred.setName("Fred");
root.setFriend(Arrays.asList(fred));
Thing xbox = new Thing();
xbox.setDescription("Xbox 360");
root.setStuff(Arrays.asList(xbox));
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(root, System.out);
}
}
This prints the same XML as the XStream example:
<root>
<friends>
<friend>
<name>Fred</name>
</friend>
</friends>
<stuff>
<stuff>
<description>Xbox 360</description>
</stuff>
</stuff>
</root>

Categories

Resources