[英]JAXB unmarshal elements of XML to Map
我有一個XML文件。 在此文件中,某些元素具有更改的屬性。 我想將這些屬性放入Map中。 我該怎么做呢?
我的XML是:
<ROW id='1'>
<MOBILE>9831138683</MOBILE>
<VARS>
<CAUSE>Delayed payment</CAUSE>
<DO>100.56</DO>
<LOT>1</LOT>
</VARS>
</ROW>
<ROW id='2'>
<MOBILE>9831138684</MOBILE>
<VARS>
<NAME>hi</NAME>
<ADDRESS>Here</ADDRESS>
<LOT>2</LOT>
</VARS>
</ROW>
在這種情況下, VARS
元素可以具有更改的屬性,並且我事先不知道這些元素將是什么。
我為此創建了一個類:
@XmlRootElement(name = "ROW")
@XmlAccessorType(XmlAccessType.FIELD)
public class SMSDetail {
@XmlAttribute
private int id;
@XmlElement(name = "MOBILE")
private int mobileNo;
@XmlElement(name = "VARS")
@XmlJavaTypeAdapter(MapAdapter.class)
private HashMap<String, String> variableMap;
public int getId() {
return id;
}
public int getMobileNo() {
return mobileNo;
}
public HashMap<String, String> getVariableMap() {
return variableMap;
}
public void setId(int id) {
this.id = id;
}
public void setMobileNo(int mobileNo) {
this.mobileNo = mobileNo;
}
public void setVariableMap(HashMap<String, String> variableMap) {
this.variableMap = variableMap;
}
}
我想將VARS
元素映射到Map
。 我希望像CAUSE
, LOT
這樣的標簽是鍵,它們的值是地圖中的值。 我為此編寫了一個XmlAdapater
:
public class MapAdapter extends XmlAdapter<MapElements[], Map<String, String>> {
public MapAdapter() {
}
@Override
public MapElements[] marshal(Map<String, String> arg0) throws Exception {
MapElements[] mapElements = new MapElements[arg0.size()];
int i = 0;
for (Map.Entry<String, String> entry : arg0.entrySet())
mapElements[i++] = new MapElements(entry.getKey(), entry.getValue());
return mapElements;
}
@Override
public Map<String, String> unmarshal(MapElements[] arg0) throws Exception {
Map<String, String> r = new TreeMap<String, String>();
for (MapElements mapelement : arg0)
r.put(mapelement.key, mapelement.value);
return r;
}
}
class MapElements {
@XmlAttribute
public String key;
@XmlAttribute
public String value;
private MapElements() {
} //Required by JAXB
public MapElements(String key, String value) {
this.key = key;
this.value = value;
}
}
這個適配器為variableMap
變量賦予null
。 應該如何修改適配器?
您可以執行以下操作:
MapAdapter
) 您可以為XmlAdapter
執行以下XmlAdapter
,將Map
的實例轉換為具有DOM Element
List
的對象。 您將構造Element
的實例,以便名稱是映射條目中的鍵,文本內容是值。
import java.util.*;
import java.util.Map.Entry;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.*;
public class MapAdapter extends XmlAdapter<MapAdapter.AdaptedMap, Map<String, String>> {
private DocumentBuilder documentBuilder;
public MapAdapter() throws Exception {
documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
}
public static class AdaptedMap {
@XmlAnyElement
public List<Element> elements = new ArrayList<Element>();
}
@Override
public AdaptedMap marshal(Map<String, String> map) throws Exception {
Document document = documentBuilder.newDocument();
AdaptedMap adaptedMap = new AdaptedMap();
for(Entry<String, String> entry : map.entrySet()) {
Element element = document.createElement(entry.getKey());
element.setTextContent(entry.getValue());
adaptedMap.elements.add(element);
}
return adaptedMap;
}
@Override
public Map<String, String> unmarshal(AdaptedMap adaptedMap) throws Exception {
HashMap<String, String> map = new HashMap<String, String>();
for(Element element : adaptedMap.elements) {
map.put(element.getLocalName(), element.getTextContent());
}
return map;
}
}
MapAdapter
的使用 為了提高性能,我們希望最小化DocumentBuiderFactory
和DocumentBuilder
實例化的次數。 我們可以通過創建MapAdapter
for JAXB的實例來MapAdapter
,並在Marshaller
和Unmarshaller
上設置它。 這樣,JAXB將在每次需要適配器時使用該實例而不是創建新實例。
import java.io.File;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(SMSDetail.class);
MapAdapter mapAdapter = new MapAdapter();
Unmarshaller unmarshaller = jc.createUnmarshaller();
unmarshaller.setAdapter(mapAdapter);
File xml = new File("src/forum27182975/input.xml");
SMSDetail smsDetail = (SMSDetail) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setAdapter(mapAdapter);
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(smsDetail, System.out);
}
}
如果您使用MOXy作為JAXB提供程序,那么您可以利用@XmlVariableNode
擴展來@XmlVariableNode
此用例的映射:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.