Java Jaxb中的地图编组问题
我有一个包含人类地图的类世界。如果我封送类世界,我会得到以下输出:Java Jaxb中的地图编组问题,java,map,jaxb,marshalling,Java,Map,Jaxb,Marshalling,我有一个包含人类地图的类世界。如果我封送类世界,我会得到以下输出: <world> <humans> <human key="2"> <value> <name>Tom</name> </value> </human> <human key="1">
<world>
<humans>
<human key="2">
<value>
<name>Tom</name>
</value>
</human>
<human key="1">
<value>
<name>Max</name>
</value>
</human>
</humans>
</world>
汤姆
马克斯
但是我不想显示“value”-标记。它应该是这样的:
<world>
<humans>
<human key="2">
<name>Tom</name>
</human>
<human key="1">
<name>Max</name>
</human>
</humans>
</world>
汤姆
马克斯
这可能吗
下面是世界级和人类级的代码:
@XmlRootElement
public class Human {
@XmlElement
private String name;
public Human(){}
}
@XmlRootElement
public class World {
private Map<String, Human> humans = new HashMap<String, Human>();
public World(){}
@XmlElementWrapper( name = "humans")
@XmlElement(name = "human")
public HumanEntry[] getMap() {
List<HumanEntry> list = new ArrayList<HumanEntry>();
for (Entry<String, Human> entry : humans.entrySet()) {
HumanEntry mapEntry =new HumanEntry();
mapEntry.key = entry.getKey();
mapEntry.value = entry.getValue();
list.add(mapEntry);
}
return list.toArray(new HumanEntry[list.size()]);
}
public void setMap(HumanEntry[] arr) {
for(HumanEntry entry : arr) {
this.humans.put(entry.key, entry.value);
}
}
public static class HumanEntry {
@XmlAttribute
public String key;
@XmlElement
public Human value;
}
public void addHuman(String key, Human human){
this.humans.put(key, human);
}
}
@XmlRootElement
公共级人员{
@XmlElement
私有字符串名称;
公共人权({}
}
@XmlRootElement
公共阶级世界{
私有映射人=新HashMap();
公共世界(){}
@XmlElementWrapper(name=“humans”)
@xmlement(name=“human”)
public HumanEntry[]getMap(){
列表=新的ArrayList();
for(条目:humans.entrySet()){
HumanEntry mapEntry=新的HumanEntry();
mapEntry.key=entry.getKey();
mapEntry.value=entry.getValue();
列表。添加(地图条目);
}
return list.toArray(新的HumanEntry[list.size()]);
}
公共无效设置映射(HumanEntry[]arr){
用于(人工输入:arr){
this.humans.put(entry.key,entry.value);
}
}
公共静态类入口{
@XmlAttribute
公共字符串密钥;
@XmlElement
公共人文价值;
}
public void addHuman(字符串键,Human-Human){
这个.人.放(键,人);
}
}
我想您正在寻找XmlValue注释:
在您的例子中,它将应用于HumanEntry.value,而不是XmlElement,正如XmlAdapter所指出的那样,可以使用将替代映射应用于JAXB中的映射(或任何类型)。下面是一个具体示例的链接:
了解更多信息
我的解决方案
我将key属性添加到human,然后将贴图转换为数组:
@XmlRootElement
public class World {
@XmlJavaTypeAdapter(HumanAdapter.class)
private Map<String, Human> humans = new HashMap<String, Human>();
public World(){}
}
public class Human {
@XmlElement
private String name;
@XmlAttribute(name="key")
private String key;
public Human(){}
}
public class HumanAdapter extends XmlAdapter<HumanJaxbCrutch, Map<String, Human>> {
@Override
public HumanJaxbCrutch marshal(Map<String, Human> humans) throws Exception {
List<Human> list = new ArrayList<Human>();
for (Entry<String, Human> entry : humans.entrySet()) {
list.add(entry.getValue());
}
HumanJaxbCrutch humanJaxbCrutch = new HumanJaxbCrutch();
humanJaxbCrutch.setCourses(list.toArray(new Human[list.size()]));
return humanJaxbCrutch;
}
@Override
public Map<String, Human> unmarshal(HumanJaxbCrutch humans) throws Exception {
Map<String, Human> map = new HashMap<String, Human>();
for(Human human : humans.getCourses()){
map.put(human.getKey(), human);
}
return map;
}
}
class HumanJaxbCrutch {
private Human[] courses;
@XmlElement(name = "human")
public Human[] getCourses() {
return courses;
}
public void setCourses(Human[] courses) {
this.courses = courses;
}
}
@XmlRootElement
公共阶级世界{
@XmlJavaTypeAdapter(HumanAdapter.class)
私有映射人=新HashMap();
公共世界(){}
}
公共级人员{
@XmlElement
私有字符串名称;
@xmltattribute(name=“key”)
私钥;
公共人权({}
}
公共类HumanAdapter扩展了XmlAdapter{
@凌驾
公共HumanJaxbCrutch封送处理(映射人)引发异常{
列表=新的ArrayList();
for(条目:humans.entrySet()){
list.add(entry.getValue());
}
HumanJaxbCrutch HumanJaxbCrutch=新的HumanJaxbCrutch();
humanJaxbCrutch.setCourses(list.toArray(新的Human[list.size()]);
返回到bcrutch;
}
@凌驾
公共映射解组(HumanJaxbCrutch humans)引发异常{
Map Map=newhashmap();
for(Human:humans.getCourses()){
map.put(human.getKey(),human);
}
返回图;
}
}
类jaxbcrutch{
私人人权课程;
@xmlement(name=“human”)
公共人权课程(){
返回课程;
}
公共课程(人类[]课程){
本课程=课程;
}
}
不幸的是@XmlValue需要引用映射到XML文本的Java类型。所以我不能使用它,特别是如果人类变得越来越复杂,你是对的“如果字段或属性的类型不是集合类型,那么该类型必须映射到XML模式简单类型”,那么我想你唯一的选择就是创建一个类型适配器use@XmlJavaTypeAdapter(HumanAdapter.class)在HumanEntry上,创建一个适配器,将HumanEntry转换为human,反之亦然,从HumanEntryThank中删除所有其他JaxB注释。请参阅我的答案以获得完整的解决方案。