I need the following DTO
@XmlRootElement(name = "exchangerate")
@XmlAccessorType(XmlAccessType.FIELD)
public class ExchRates {
@XmlJavaTypeAdapter(DateAdapter.class)
private Date date;
@XmlJavaTypeAdapter(JaxbExchangeRatesMapAdapter.class)
private Map<CurrencyUnit, Map<CurrencyUnit, Double>> rates = new HashMap<>();
}
How can I unmarshal this xml into the DTO above?
<exchangerate>
<date>2015-05-04</date>
<EUR>
<EUR>1</EUR>
<GBP>0.73788</GBP>
<USD>1.1152</USD>
</EUR>
<GBP>
<EUR>1.35523</EUR>
<GBP>1</GBP>
<USD>1.51136</USD>
</GBP>
<USD>
<EUR>0.8967</EUR>
<GBP>0.66166</GBP>
<USD>1</USD>
</USD>
</exchangerate>
I read some tutorials and examples but I found no one where all keys are the node values of the xml.
Edit
After some hours I'm close to a solution.
My XmlAdapter:
public class JaxbExchangeRatesMapAdapter extends XmlAdapter<JaxbExchangeRatesMap, Map<CurrencyUnit, Map<CurrencyUnit, Double>>> {
@Override
public Map<CurrencyUnit, Map<CurrencyUnit, Double>> unmarshal(JaxbExchangeRatesMap v) throws Exception {
return null;
}
@Override
public JaxbExchangeRatesMap marshal(Map<CurrencyUnit, Map<CurrencyUnit, Double>> v) throws Exception {
JaxbExchangeRatesMap map = new JaxbExchangeRatesMap();
for (CurrencyUnit currencyFrom : v.keySet()) {
Map<CurrencyUnit, Double> from = v.get(currencyFrom);
JaxbExchangeRatesEntry entry = new JaxbExchangeRatesEntry();
for (CurrencyUnit currencyTo : from.keySet()) {
entry.getEntries().add(new JAXBElement<>(new QName(currencyTo.getCurrencyCode()), Double.class, from.get(currencyTo)));
}
JAXBElement<JaxbExchangeRatesEntry> jaxbElement = new JAXBElement<>(new QName(currencyFrom.getCurrencyCode()), JaxbExchangeRatesEntry.class, entry);
map.getEntires().add(jaxbElement);
}
return map;
}
}
And my mapped classes:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlSeeAlso(JaxbExchangeRatesEntry.class)
public class JaxbExchangeRatesMap extends Printable {
private static final long serialVersionUID = 15543456767150881L;
@XmlAnyElement
private List<JAXBElement<JaxbExchangeRatesEntry>> entires = new ArrayList<>();
public List<JAXBElement<JaxbExchangeRatesEntry>> getEntires() {
return entires;
}
public JaxbExchangeRatesMap setEntires(List<JAXBElement<JaxbExchangeRatesEntry>> entires) {
this.entires = entires;
return this;
}
}
@XmlAccessorType(XmlAccessType.FIELD)
public class JaxbExchangeRatesEntry extends Printable {
private static final long serialVersionUID = -694282168028218725L;
@XmlAnyElement
private List<JAXBElement<Double>> entries = new ArrayList<>();
public List<JAXBElement<Double>> getEntries() {
return entries;
}
public JaxbExchangeRatesEntry setEntries(List<JAXBElement<Double>> entries) {
this.entries = entries;
return this;
}
}
With that I got the following result:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<exchangerate>
<rates>
<USD>
<USD>9.0</USD>
<EUR>7.0</EUR>
<GBP>8.0</GBP>
</USD>
<EUR>
<USD>3.0</USD>
<EUR>1.0</EUR>
<GBP>2.0</GBP>
</EUR>
<GBP>
<USD>6.0</USD>
<EUR>4.0</EUR>
<GBP>5.0</GBP>
</GBP>
</rates>
</exchangerate>
How can I remove/skip the rates tag?