I am trying to marshall a list of objects implementing a common interface. There are 3 classes and 1 interface involved:
Community class (has one method: List<Person> getPeople();)
Person interface (has one method: String getName();)
Girl class (implements Person)
Boy class (implements Person)
See code below.
I want an XML that looks something like this:
<community> <people> <girl> <name>Jane</name> </girl> <boy> <name>John</name> </boy> <girl> <name>Jane</name> </girl> <boy> <name>John</name> </boy> </people> </community>
or possibly:
<community> <people> <person> <girl> <name>Jane</name> </girl> </person> <person> <boy> <name>John</name> </boy> </person> </people> </community>
So far what I get is this:
<community> <people> <person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="girl"> <name>Jane</name> </person> <person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="boy"> <name>John</name> </person> <person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="girl"> <name>Jane</name> </person> <person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="boy"> <name>John</name> </person> </people> </community>
I realize I can change the element to something else, but I want the element name to be the name spesified in the Girl or Boy class.
Can this be done? Thanks.
@XmlRootElement(name = "community") public class Community { private List<Person> people; @XmlElementWrapper @XmlElement(name="person") public List<Person> getPeople() { return people; } public Community() { people = new ArrayList<Person>(); people.add(new Girl()); people.add(new Boy()); people.add(new Girl()); people.add(new Boy()); } } @XmlRootElement(name = "girl") public class Girl implements Person { @XmlElement public String getName() { return "Jane"; } } @XmlRootElement(name = "boy") public class Boy implements Person { @XmlElement public String getName() { return "John"; } } @XmlJavaTypeAdapter(AnyTypeAdapter.class) public interface Person { public String getName(); } public class AnyTypeAdapter extends XmlAdapter<Object, Object> { @Override public Object marshal(Object v) throws Exception { return v; } @Override public Object unmarshal(Object v) throws Exception { return v; } }
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.
public List<T> Unmarshal(List<Entry> entries, Class clazz) { List<T> out = new ArrayList<T>(); T instance; for (Entry e : entries) { try { JAXBContext context = JAXBContext. newInstance(clazz); Unmarshaller unmarsh = context.
In the Java-related RFC 2713, marshalling is used when serialising objects for remote invocation. An object that is marshalled records the state of the original object and it contains the codebase (codebase here refers to a list of URLs where the object code can be loaded from, and not source code).
For this scenario I would recommend the use of @XmlElements. @XmlElements is used to represent the XML schema concept of choice:
Here is how it would look for your example:
@XmlElements({ @XmlElement(name="girl", type=Girl.class), @XmlElement(name="boy", type=Boy.class) }) @XmlElementWrapper public List<Person> getPeople() { return people; }
@XmlElementRef corresponds to the concept of substitution groups in XML schema. This is why the previous answer requires Person to be changed from an interface to a class.
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