jaxb对Map的处理很简单粗暴
package com.test;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name="MyRootElement")
public class XmlAdapter {
@XmlElement
@XmlElementWrapper(name="People")
private Map<Integer, String> people = new HashMap<>();
public static void main(String[] args) throws Exception {
XmlAdapter root = new XmlAdapter();
root.getPeople().put(1, "One");
root.getPeople().put(2, "Two");
root.getPeople().put(3, "Three");
JAXBContext context = JAXBContext.newInstance(XmlAdapter.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.marshal(root, System.out);
}
public Map<Integer, String> getPeople() {
return people;
}
}
输出如下。估计没有人会用这种XML schema
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<MyRootElement>
<People>
<entry>
<key>1</key>
<value>One</value>
</entry>
<entry>
<key>2</key>
<value>Two</value>
</entry>
<entry>
<key>3</key>
<value>Three</value>
</entry>
</People>
</MyRootElement>
用XmlAdapter可以自定义绑定.
package com.test;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlValue;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@XmlRootElement(name="MyRootElement")
@XmlAccessorType(XmlAccessType.FIELD)
public class XmlAdapter2 {
@XmlElement(name="mypeoplemap")
@XmlJavaTypeAdapter(MyMapAdapter.class)
private Map<Integer, String> peopleMap = new HashMap<>();
public static void main(String[] args) throws Exception {
XmlAdapter2 root = new XmlAdapter2();
root.getPeopleMap().put(1, "One");
root.getPeopleMap().put(2, "Two");
root.getPeopleMap().put(3, "Three");
JAXBContext context = JAXBContext.newInstance(XmlAdapter2.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.marshal(root, System.out);
}
public Map<Integer, String> getPeopleMap() {
return peopleMap;
}
}
@XmlAccessorType(XmlAccessType.FIELD)
class People {
@XmlAttribute
private Integer id;
@XmlValue
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@XmlAccessorType(XmlAccessType.FIELD)
class PeopleList {
@XmlElement(name="people")
private List<People> peopleList = new ArrayList<>();;
public List<People> getPeopleList() {
return peopleList;
}
}
class MyMapAdapter extends XmlAdapter<PeopleList, Map<Integer, String>> {
@Override
public PeopleList marshal(Map<Integer, String> peopleMap) throws Exception {
PeopleList peopleList = new PeopleList();
for (Integer key: peopleMap.keySet()) {
People p = new People();
p.setId(key);
p.setName(peopleMap.get(key));
peopleList.getPeopleList().add(p);
}
return peopleList;
}
@Override
public Map<Integer, String> unmarshal(PeopleList peopleList) throws Exception {
Map<Integer, String> map = new HashMap<>();
for (People p: peopleList.getPeopleList()) {
map.put(p.getId(), p.getName());
}
return map;
}
}
输出
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<MyRootElement>
<mypeoplemap>
<people id="1">One</people>
<people id="2">Two</people>
<people id="3">Three</people>
</mypeoplemap>
</MyRootElement>
为了这种格式的输出,写了3个辅助类。一个代表map的entry的类People,一个类似容器的PeopleList类,还有一个adapter类。真正干活的是adapter类。另外还要注意要用@XmlJavaTypeAdapter注册这个adapter类
public class XmlAdapter2 {
@XmlElement(name="mypeoplemap")
@XmlJavaTypeAdapter(MyMapAdapter.class)
private Map<Integer, String> peopleMap = new HashMap<>();