With an XmlAdapter
on a Map
(to convert the Map
to a domain object with a List
of Register
objects) you are going to be able to produce/consume XML that looks like the following (Note the addition of the registers
element):
<root attribute1="blabla" attribute2="blablabla">
<registers>
<register type="1" description="blabla">
<field description = "blabla" type = "blabla">
</register>
<register type="2" description="blabla">
<field description = "blabla" type = "blabla">
</register>
</registers>
</root>
If you use EclipseLink MOXy as your JAXB provider, then you can use our @XmlPath
extension to get rid of that extra element.
@XmlJavaTypeAdapter(MapAdapter.class) // Standard JAXB annotation
@XmlPath(".") // MOXy extension
private Map<String, Register> registers;
UPDATE
Unfortunatelly I can't use MOXy in this project and I can't change the
xml. Is there any way of parsing it without the registers tag?
This isn't the prettiest solution, but you could do the following (note: with this solution it is not safe to marshal the same instance of Root
concurrently):
import java.util.*;
import javax.xml.bind.annotation.*;
@XmlRootElement
public class Root {
private Map<String, Register> registers = new HashMap<String, Register>();
@XmlElement(name="register")
private Collection<Register> registerCollection;
@XmlTransient
public Map<String, Register> getRegisters() {
return registers;
}
public void setRegisters(Map<String, Register> registers) {
this.registers = registers;
}
private void afterUnmarshal(Unmarshaller unmarshaller, Object parent) {
for (Register register : registerCollection) {
regusters.put(register.getType());
}
}
private void beforeMarshal(Marshaller marshaller) {
if(null != registers) {
registerCollection = registers.values();
}
}
}