Reputation: 279880
I'm playing around with JAXB, so a lot of the questions I'm asking are just to see what's possible.
I have the following XML:
<bundleMappings>
<mapping>
<parameter attr = "value">asdas</parameter>
<parameter attr = "value2">d123asdsad</parameter>
<parameter attr = "value3">0</parameter>
</mapping>
<mapping>
<parameter attr = "value">23123s</parameter>
<parameter attr = "value2">qwerty</parameter>
<!-- more parameter elements -->
</mapping>
<!-- more mapping elements -->
</bundleMappings>
In which I'd want the parameter
elements to be in a Map<String, Parameter>
instead of a List, where the key is the attr
value and the value is the content of the element. I've followed some blog posts and come up with this.
@XmlRootElement(name = "bundleMmappings")
public class BundleMappings {
@XmlElement(name = "mapping")
private List<Mapping> mMappings;
//getters setters
}
@XmlAccessorType(XmlAccessType.FIELD)
public class Mapping {
@XmlElement
@XmlJavaTypeAdapter(ParameterAdapter.class)
private HashMap<String, Parameter> mParameterMap;
//getters setters
}
@XmlAccessorType(XmlAccessType.FIELD)
public class Parameter {
@XmlAttribute(name = "attr")
private String mName;
@XmlValue
private String mValue;
//getters setters
}
@XmlAccessorType(XmlAccessType.FIELD)
public class Parameters {
@XmlElement(name = "parameters")
private List<Parameter> parameters = new LinkedList<>();
//getters setters
}
And the adapter:
public class ParameterAdapter extends XmlAdapter<Parameters, Map<String, Parameter>> {
@Override
public Parameters marshal(Map<String, Parameter> map) throws Exception {
Parameters params = new Parameters();
params.setParameters(new ArrayList<Parameter>());
for (String name : map.keySet()) {
Parameter p = new Parameter();
p.setName(name);
p.setValue(map.get(name).getValue());
params.getParameters().add(p);
}
return params;
}
@Override
public Map<String, Parameter> unmarshal(Parameters value) throws Exception {
Map<String, Parameter> map = new HashMap<>();
for (Parameter parameter : value.getParameters()) {
map.put(parameter.getName(), parameter);
}
return map;
}
}
I did a small unmarshalling test with breakpoints in the Adapter unmarshal
and it isn't called at all. Why not?
I also tried annotating the Mapping
class List
with @XmlElement(name = "parameter")
. In this case the unmarshall
was called but the Parameters
parameter passed to it had an empty list.
Edit
If I try to marshal:
<bundleMappings>
<mapping>
<mParameterMap>
<parameter name="HOME_NETWORK_ID">12345</parameter>
</mParameterMap>
</mapping>
</bundleMappings>
Upvotes: 2
Views: 1934
Reputation: 148977
When you specify an XmlAdapter
on a collection property it applies to the items in the collection.
public class Mapping {
@XmlElement
@XmlJavaTypeAdapter(ParameterAdapter.class)
private List<Parameter> mParameters;
//getters setters
}
This means ParameterAdapter
would need to look something like, where Foo
is what you want to convert Parameter
to:
public class ParameterAdapter extends XmlAdapter<Foo, Parameter> {
Map Example
Below is a link to an example from my blog where XmlAdapter
is used on a Map
property:
Upvotes: 2