I found a lot of articles that describe how to unmarshal a sequence of XML elements to a HashMap as long as they are within a \"parent\" element. However, I do not get this to w
Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.
JAXB will treat each object relationship with a nesting relationship. Map
is treated like an Object
instead of a Collection
so this is why you are getting the behaviour that you are seeing.
MOXy has an XPath based mapping extension called @XmlPath
that could be used for this use case.
package com.foo.conf;
import java.util.Map;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.eclipse.persistence.oxm.annotations.XmlPath;
@XmlRootElement(name="checks")
public class Checks {
@XmlJavaTypeAdapter(ChecksAdapter.class)
@XmlPath(".")
public Map<String, Check> checkMap;
}
For More Information
How are you generaing the JAXB classes? I am not sure what exactly are you trying to do but the below very simple code works for me ..
JAXBContext jc = JAXBContext.newInstance(ChecksType.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
ChecksType chksType = (ChecksType) unmarshaller.unmarshal(new File("/path/to/xml"));
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(chksType, System.out);
System.err.println(chksType.getCheck().get(0).getKey());
for (CheckType checkType : chksType.getCheck()) {
System.out.println("key = " + checkType.getKey() + ", " + checkType);
}
and here is my JAXB generated classes ..
ChecksType
(Root element)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "checksType", propOrder = { "check" })
@XmlRootElement(name = "checks")
public class ChecksType {
@XmlElement(required = true)
protected List<CheckType> check;
public List<CheckType> getCheck() {
if (check == null) {
check = new ArrayList<CheckType>();
}
return this.check;
}
}
And checkType
(the child)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "checkType")
public class CheckType {
@XmlAttribute(name = "key")
protected String key;
public String getKey() {
return key;
}
public void setKey(String value) {
this.key = value;
}
}