I have a class like this
public class Item {
#XmlElement(name = "my_id")
private String id;
#XmlElement(name = "my_type")
private String type;
}
I would like to convert this class to a Map which considers the jaxb annotated fields.
E.g. the Result is a map with following entries:
Key: my_id , Value: "the id"
Key: my_type , Value: "the type"
I am not sure how your xml looks like but assuming, it will be an item element, under some parent, you can do it usingadapter (XmlJavaTypeAdapter) . Sample code looks like below:
package test;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Map;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
#XmlAccessorType(XmlAccessType.FIELD)
public class Item {
public Item() {
}
#XmlElement(name = "my_id")
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
#XmlElement(name = "my_type")
private String type;
public String toString() {
return "Item : id-" + getId() + ", type -" + getType();
}
public static void main(String[] args) throws Exception {
String xmlString = "<items>\n"
+ " <item>\n"
+ " <my_id>someID</my_id>\n"
+ " <my_type>someType</my_type>\n"
+ " </item>\n"
+ "</items>";
//System.out.println("xmlString.." + xmlString);
RootElement o = unmarshal(RootElement.class, xmlString);
System.out.println("item Map : "+o.getItem());
}
private static <C> C unmarshal(Class<C> c, String sampleXML) throws Exception {
JAXBContext jc = JAXBContext.newInstance(c);
Unmarshaller unmarshaller = jc.createUnmarshaller();
StringReader reader = new StringReader(sampleXML);
//System.out.println("" + sampleXML);
return (C) unmarshaller.unmarshal(reader);
}
}
#XmlRootElement(name = "items")
#XmlAccessorType(XmlAccessType.FIELD)
class RootElement {
public RootElement() {
System.out.println("RootElement");
}
public Map<String, String> getItem() {
return item;
}
public void setItem(Map<String, String> item) {
this.item = item;
}
#XmlJavaTypeAdapter(ItemAdapter.class)
#XmlElement()
private Map<String, String> item;
}
class ItemAdapter extends XmlAdapter<Item, Map<String, String>> {
#Override
public Map<String, String> unmarshal(Item i) throws Exception {
Map<String, String> r = new HashMap<String, String>();
r.put("my_id", i.getId());
r.put("my_type", i.getType());
return r;
}
#Override
public Item marshal(Map<String, String> v) throws Exception {
Item i = new Item();
i.setId(v.get("my_id"));
i.setType(v.get("my_type"));
return i;
}
}
Related
I'm trying to deserialize some xml with nested properties with the same name, but the wrapper name is unique for each property. Example XML below.
I've tried playing with switching wrapper and property names but doesn't seem to work.
<response>
<string>
<item>Sample string.</item>
<item>Another sample string.</item>
</string>
<number>
<item>123123123</item>
<item>900912</item>
</number>
</response>
I'm trying to deserialize the above XML into a List<String> and List<Integer> variable.
I managed to make it creating a pair or wrappers of ArrayLists as inner classes:
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
#JacksonXmlRootElement(localName="response")
public class ResponseObjectList implements Serializable {
#JacksonXmlProperty(localName = "string")
private StringArrayListContainer string;
#JacksonXmlProperty(localName = "number")
private IntegerArrayListContainer number;
public ResponseObjectList() {
super();
}
public ResponseObjectList(List<String> stringItems, List<Integer> intItems) {
super();
this.string = new StringArrayListContainer(stringItems);
this.number = new IntegerArrayListContainer(intItems);
}
public StringArrayListContainer getString() {
return string;
}
public void setString(StringArrayListContainer string) {
this.string = string;
}
public IntegerArrayListContainer getNumber() {
return number;
}
public void setNumber(IntegerArrayListContainer number) {
this.number = number;
}
public static class StringArrayListContainer extends ArrayListContainer<String>{
public StringArrayListContainer() {
super();
}
public StringArrayListContainer(List<String> item) {
super(item);
}
}
public static class IntegerArrayListContainer extends ArrayListContainer<Integer>{
public IntegerArrayListContainer() {
super();
}
public IntegerArrayListContainer(List<Integer> item) {
super(item);
}
}
public static class ArrayListContainer<T extends Serializable>{
#JacksonXmlElementWrapper(useWrapping=false)
#JacksonXmlProperty(localName="item")
private List<T> item;
public ArrayListContainer(List<T> item) {
super();
this.item = item;
}
public ArrayListContainer() {
super();
}
public List<T> getItem() {
return item;
}
public void setItem(List<T> item) {
this.item = item;
}
}
}
Tests looked good:
#Test
public void test3() throws JsonProcessingException {
ResponseObjectList response = new ResponseObjectList(
Arrays.asList(new String[] {"Sample string.","Another sample string"}),
Arrays.asList(new Integer[] {123123123,900912})
);
XmlMapper xmlMapper = new XmlMapper();
String content = xmlMapper.writeValueAsString(response);
this.logger.debug("content: " + content);
// content: <response xmlns=""><string><item>Sample string.</item><item>Another sample string</item></string><number><item>123123123</item><item>900912</item></number></response>
}
#Test
public void test4() throws JsonParseException, JsonMappingException, IOException {
String xml =
"<response>"
+ "<string>"
+ "<item>Sample string.</item>"
+ "<item>Another sample string</item>"
+ "</string>"
+ "<number>"
+ "<item>123123123</item>"
+ "<item>900912</item>"
+ "</number>"
+ "</response>";
XmlMapper xmlMapper = new XmlMapper();
ResponseObjectList object = xmlMapper.readValue(xml, ResponseObjectList.class);
Assert.assertFalse(object.getString().getItem().isEmpty());
Assert.assertFalse(object.getNumber().getItem().isEmpty());
}
I used Lists instead of ArrayLists both for the wrappers and the tests
For version 2.9.9 simple POJO with JacksonXmlElementWrapper annotation works as expected:
class Response {
#JacksonXmlElementWrapper(localName = "string")
private List<String> strings;
#JacksonXmlElementWrapper(localName = "number")
private List<Integer> numbers;
// getters, setters
}
I have a JSON as below. The goal is to get the corresponding "ip","PRODUCTTYPE" and "ID" values.
{
"customerId": "dummy1",
"nameIdmap": {
"10.2.1.0": "{PRODUCTTYPE=null, ID=123}",
"10.2.1.3": "{PRODUCTTYPE=null, ID=456}",
"10.2.1.4": "{PRODUCTTYPE=null, ID=789}",
"10.2.1.5": "{PRODUCTTYPE=null, ID=193}"
}
}
I am using the ObjectMapper API to parse and fetch the values.
ObjectMapper om = new ObjectMapper();
JsonNode node = om.readTree(stringToBeParsed);
String customerID = node.get("customerId").asText();
System.out.println("The Customer ID is ::: "+customerID);
JsonNode nameIdmap = node.get("nameIdmap");
StreamSupport.stream(nameIdmap.spliterator(), false).forEach(
kv -> {
System.out.println(kv.asText().split(",")[0] +" ,
"+kv.asText().split(",")[1]);
});
But the issue is I, am unable to get the key which is the ip-address in this case. Tried different ways to achieve but could not get what i want.
I checked if the nameIdmap is an array nameIdmap.isArray() but it is false.
I also tried below but could not get the ip i.e the key
JsonNode nameIdmap = node.get("nameIdmap");
StreamSupport.stream(nameIdmap.spliterator(), false).collect(Collectors.toList())
.forEach(item -> {
System.out.println(item.asText());
});;
You can try Custom Deserializer as below
1. Create Item class
This is a POJO which stands for an ID and a map of String and IPItem
public class SOItem {
#Override
public String toString() {
return "SOItem [id=" + id + ", map=" + map + "]";
}
String id;
Map<String, SOIPItem> map = new HashMap();
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Map<String, SOIPItem> getMap() {
return map;
}
public void setMap(Map<String, SOIPItem> map) {
this.map = map;
}
}
2. Create IPItem class
This is a POJO for an ID and ProductType
public class SOIPItem {
private String type;
private String id;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
#Override
public String toString() {
return "SOIPItem [type=" + type + ", id=" + id + "]";
}
public SOIPItem(String type, String id) {
super();
this.type = type;
this.id = id;
}
}
3. Create a Custom Deserializer
import java.io.IOException;
import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
public class SOCustDeser extends StdDeserializer<SOItem> {
public SOCustDeser() {
this(null);
}
public SOCustDeser(Class<?> vc) {
super(vc);
}
/**
*
*/
private static final long serialVersionUID = -394222274225082713L;
#Override
public SOItem deserialize(JsonParser parser, DeserializationContext arg1)
throws IOException, JsonProcessingException {
SOItem soItem = new SOItem();
ObjectCodec codec = parser.getCodec();
JsonNode node = codec.readTree(parser);
soItem.setId(node.get("customerId").asText());
JsonNode idmap = node.get("nameIdmap");
Iterator<String> fieldNames = idmap.fieldNames();
while(fieldNames.hasNext()) {
String ip = fieldNames.next();
String textValue = idmap.get(ip).asText();
Pattern p = Pattern.compile("(.*?)=(.*?),(.*?)(\\d+)");
Matcher m = p.matcher(textValue);
if (m.find()) {
soItem.map.put(ip, new SOIPItem(m.group(2), m.group(4)));
}
}
return soItem;
}
}
4. Test class
import java.io.File;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
public class MicsTest {
public static void main(String[] args) throws Exception {
ObjectMapper om = new ObjectMapper();
SimpleModule sm = new SimpleModule();
sm.addDeserializer(SOItem.class, new SOCustDeser());
om.registerModule(sm);
SOItem item = om.readValue(new File("c:\\temp\\test.json"), SOItem.class);
System.out.println(item);
}
}
5. Output
SOItem [id=dummy1, map={10.2.1.0=SOIPItem [type=null, id=123], 10.2.1.3=SOIPItem [type=null, id=456], 10.2.1.5=SOIPItem [type=null, id=193], 10.2.1.4=SOIPItem [type=null, id=789]}]
You can get the field names by nameIdmap.getFieldNames as an iterator. You can then iterate over like that:
...
Iterator<String> fieldNames = idmap.getFieldNames();
while(fieldNames.hasNext()) {
String ip = fieldNames.next();
String textValue = idmap.get(ip).getTextValue()
System.out.println(ip + ":" + textValue);
}
If the nested information is also JSON you can then access it further via idmap.get(ip).get("ID"); if not then you still have the option to find it by regex like that:
Pattern p = Pattern.compile("ID=(\\d+)");
Matcher m = p.matcher(textValue);
if(m.find()) {
System.out.println(ip + ":" + m.group(1));
}
Best way to handle these scenarios is to create a matching pojo for your json. This way it gives you flexibility to play around with the data.
Create classes like these
public class Someclass {
private String customerId;
Map<String, String> nameIdmap;
public Map<String, String> getNameIdmap() {
return nameIdmap;
}
public void setNameIdmap(Map<String, String> nameIdmap) {
this.nameIdmap = nameIdmap;
}
public Someclass() {
}
public String getCustomerId() {
return customerId;
}
public void setCustomerId(String customerId) {
this.customerId = customerId;
}
}
And this code will translate your json to SomeClass class
String json = "<copy paste your json here>";
Someclass someclass = objectMapper.readValue(json, Someclass.class);
String s = someclass.getNameIdmap().get("10.2.1.0");
String[] splits = s.split(" ");
String productType = splits[0].split("=")[1];
String id = splits[1].split("=")[1];
System.out.println(productType + " " + id);
I have the following XML:
<object>
<name>Test</name>
<bikes>
<bike key="Hello" value="World"/>
</bikes>
</object>
So I then have the following Objects:
#XmlRootElement
public class Object {
#XmlElement
private String name;
#XmlElement
private Bikes bikes;
public Object(String name, Bikes bikes) {
this.name = name;
this.bikes = bikes;
}
Bikes
public class Bikes{
private Map<String, String> bike = new HashMap();
#XmlElement
public Bikes(Map<String, String> bike) {
this.bike = bike;
}
I have tried to unmarshall the xml into the the above classes but I am not sure how.
Found a couple of answers on here but none seemed to work as I needed.
You shall be able to do it using adapter class. here is a working case.
Object.java
The class has XmlJavaTypeAdapter(BikeAdapter.class) annoted to bikes map. Adapter and wrapper class are defined here itself.
package testjaxb;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Object {
#XmlElement
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Map<String, String> getBikes() {
return bikes;
}
public void setBikes(Map<String, String> bikes) {
this.bikes = bikes;
}
#XmlJavaTypeAdapter(BikeAdapter.class)
private Map<String, String> bikes;
public Object() {
}
}
class BikeWrapper {
#XmlElement(name = "bike")
List<Bike> bike = new ArrayList<Bike>();
}
class BikeAdapter extends XmlAdapter<BikeWrapper, Map<String, String>> {
public BikeWrapper marshal(Map<String, String> arg0) throws Exception {
BikeWrapper bw = new BikeWrapper();
List<Bike> bikes = new ArrayList<Bike>();
for (Map.Entry<String, String> entry : arg0.entrySet()) {
bikes.add(new Bike(entry.getKey(), entry.getValue()));
}
bw.bike = bikes;
return bw;
}
public Map<String, String> unmarshal(BikeWrapper arg0) throws Exception {
Map<String, String> r = new HashMap<String, String>();
for (Bike mapelement : arg0.bike) {
r.put(mapelement.getKey(), mapelement.getValue());
}
return r;
}
}
Bike.jaa
package testjaxb;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
#XmlAccessorType(XmlAccessType.FIELD)
public class Bike {
#XmlAttribute()
private String key;
public Bike() {
}
public Bike(String key, String value) {
this.key = key;
this.value = value;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
#XmlAttribute()
private String value;
public String toString() {
return "Bike : key-" + getKey() + ", value -" + getValue();
}
}
And here is your Main class to test.
package testjaxb;
import java.io.StringReader;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
public class Main {
public static void main(String[] args) throws Exception {
String xmlString = "<object>\n"
+ " <name>Test</name>\n"
+ " <bikes>\n"
+ " <bike key=\"Hello\" value=\"World\"/>\n"
+ " </bikes>\n"
+ "</object>";
testjaxb.Object o = unmarshal(testjaxb.Object.class, xmlString);
System.out.println("Bike List.." + o.getBikes());
}
private static <C> C unmarshal(Class<C> c, String sampleXML) throws Exception {
JAXBContext jc = JAXBContext.newInstance(c);
Unmarshaller unmarshaller = jc.createUnmarshaller();
StringReader reader = new StringReader(sampleXML);
//System.out.println("" + sampleXML);
return (C) unmarshaller.unmarshal(reader);
}
}
I am trying to convert my below xml to java object.
This is my xml:
<ClinicalDocument xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:hl7-org:v3" xmlns:sdtc="urn:hl7-org:sdtc" xmlns:voc="urn:hl7-org:v3/voc">
<confidentialityCode code="" codeSystem=""/>
<languageCode code="en-"/>
<recordTarget>
<patientRole>
<id root="" extension=""/>
<telecom value="" use=""/>
<providerOrganization>
<id root="" extension=""/>
<id root="" extension=""/>
<name>Something</name>
<telecom value=""/>
<addr use="">
<state></state>
<city></city>
<postalCode></postalCode>
<streetAddressLine>2121</streetAddressLine>
</addr>
</providerOrganization>
</patientRole>
</recordTarget>
</ClinicalDocument>
I need to get the value of "name" under "providerOrganization".
Below are my Java classes.
ClinicalDocument.java
package com.biclinical.data;
import java.util.List;
import javax.xml.bind.annotation.*;
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement(name="ClinicalDocument", namespace="urn:hl7-org:v3")
public class ClinicalDocument {
#XmlElement(name="recordTarget")
private List<RecordTarget> recordTarget;
public List<RecordTarget> getRecordTarget() {
return recordTarget;
}
public void setRecordTarget(List<RecordTarget> recordTarget) {
this.recordTarget = recordTarget;
}
#Override
public String toString() {
return "ClinicalDocument [recordTarget=" + recordTarget + "]";
}
}
RecordTarget.java
package com.biclinical.data;
import java.util.List;
import javax.xml.bind.annotation.*;
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement(name="recordTarget")
public class RecordTarget {
#XmlElement(name="patientRole")
private List<PatientRole> patientRole;
public List<PatientRole> getPatientRole() {
return patientRole;
}
public void setPatientRole(List<PatientRole> patientRole) {
this.patientRole = patientRole;
}
#Override
public String toString() {
return "RecordTarget [patientRole=" + patientRole +"]";
}
}
PatientRole.java
package com.biclinical.data;
import java.util.List;
import javax.xml.bind.annotation.*;
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement(name = "patientRole")
public class PatientRole {
/*#XmlElement(name = "id")
private String id;
Double root;
String extension;*/
#XmlElement(name="providerOrganization")
private List<ProviderOrganization> providerOrganization;
public List<ProviderOrganization> getProviderOrganization() {
return providerOrganization;
}
public void setProviderOrganization(List<ProviderOrganization> providerOrganization) {
this.providerOrganization = providerOrganization;
}
}
ProviderOrganisation.java
package com.biclinical.data;
import javax.xml.bind.annotation.*;
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement(name="providerOrganization")
public class ProviderOrganization {
#XmlElement(name="name")
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public String toString() {
return "Patient [Name=" + name + "]";
}
}
XMLFileParserSAXUtility.java
public class XMLFileParserSAXUtility extends DefaultHandler {
public static void main(String[] args) {
try {
File file = new File("C:/Users/shivendras/Desktop/Patient19999_Test_Organization1.xml");
JAXBContext jaxbContext = JAXBContext.newInstance(new Class[] {ClinicalDocument.class,RecordTarget.class,PatientRole.class,ProviderOrganization.class});
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
ClinicalDocument clinicalDocument = (ClinicalDocument) jaxbUnmarshaller.unmarshal(file);
//clinicalDocument.getRecordTarget()
String s = ((File) ((PatientRole) ((RecordTarget) clinicalDocument.getRecordTarget()).getPatientRole()).getProviderOrganization()).getName();
System.out.println(s);
} catch (JAXBException e) {
e.printStackTrace();
}
}
I get the result as
Exception in thread "main" java.lang.NullPointerException
at com.biclinical.util.XMLFileParserSAXUtility.main(XMLFileParserSAXUtility.java:27)
And if i try to print syso(clinicalDocument);
Result is ClinicalDocument [recordTarget=null]
Please help me out here!
I think you add the namespace to your #XmlElement :
#XmlElement(name="patientRole")
private List<PatientRole> patientRole;
Should be :
#XmlElement(name="patientRole",namespace="urn:hl7-org:v3")
private List<PatientRole> patientRole;
If you're having any other null in your objects, try adding the namespace.
Also, #XmlRootEntity is only necessary for your root element, in this case your ClinicalDocumentclass, and you only need to give the root class to your JAXBContext :
JAXBContext jaxbContext = JAXBContext.newInstance(ClinicalDocument.class);
I need something like this -
<Token>
<HighLevel info-1="" info-2=""/>
<LowLevel>
<LowLevel info-key="" info-value=""/>
<LowLevel info-key="" info-value=""/>
....
</LowLevel>
</Token >
I've the Map for LowLevel element, whose entries I want to populate like above XML.
What could be the way to encapsulate/bind this using JAXB?
You could use a custom adapter for this. Example
//Token.java
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
#XmlRootElement
class LowLevelToken {
#XmlAttribute(name = "info-key")
public String key;
#XmlAttribute(name = "info-value")
public String value;
private LowLevelToken() {}
public LowLevelToken(String key, String value) {
this.key = key;
this.value = value;
}
}
#XmlRootElement
class HighLevelToken {
#XmlAttribute(name = "info-1")
public String info1;
#XmlAttribute(name = "info-2")
public String info2;
private HighLevelToken() {}
public HighLevelToken(String info1, String info2) {
this.info1 = info1;
this.info2 = info2;
}
}
class TokenWrapper {
#XmlElement(name="LowLevel")
public List<LowLevelToken> tokens = new ArrayList<LowLevelToken>();
}
class TokenAdapter extends XmlAdapter<TokenWrapper, Map<String, String>> {
#Override
public TokenWrapper marshal(Map<String, String> lowlevelTokens)
throws Exception {
TokenWrapper wrapper = new TokenWrapper();
List<LowLevelToken> elements = new ArrayList<LowLevelToken>();
for (Map.Entry<String, String> property : lowlevelTokens.entrySet()) {
elements.add(new LowLevelToken(property.getKey(), property.getValue()));
}
wrapper.tokens = elements;
return wrapper;
}
#Override
public Map<String, String> unmarshal(TokenWrapper tokenWrapper) throws Exception {
Map<String, String> tokens = null;
if(tokenWrapper != null && tokenWrapper.tokens != null && !tokenWrapper.tokens.isEmpty()){
tokens = new HashMap<String, String>();
for(LowLevelToken token : tokenWrapper.tokens){
tokens.put(token.key, token.value);
}
}
return tokens;
}
}
#XmlRootElement(name = "Token")
public class Token {
HighLevelToken highLevel;
Map<String, String> lowLevel;
public HighLevelToken getHighLevel() {
return highLevel;
}
#XmlElement(name = "HighLevel")
public void setHighLevel(HighLevelToken highLevel) {
this.highLevel = highLevel;
}
public Map<String, String> getLowLevel() {
return lowLevel;
}
#XmlElement(name = "LowLevel")
#XmlJavaTypeAdapter(TokenAdapter.class)
public void setLowLevel(Map<String, String> lowLevel) {
this.lowLevel = lowLevel;
}
}
A sample program
import java.util.HashMap;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
public class JAXBExample {
public static void main(String[] args) {
Token token = new Token();
token.setHighLevel(new HighLevelToken("1", "2"));
token.setLowLevel(new HashMap<String, String>() {{ put("LK1", "LV1"); put("LK2", "LV2"); put("LK2", "LV2"); }});
try {
JAXBContext jaxbContext = JAXBContext.newInstance(Token.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxbMarshaller.marshal(token, System.out);
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
This generates
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Token>
<HighLevel info-1="1" info-2="2"/>
<LowLevel>
<LowLevel info-key="LK2" info-value="LV2"/>
<LowLevel info-key="LK1" info-value="LV1"/>
</LowLevel>
</Token>