我正在尝试将xml元素列表反序列化为Map,其中id属性作为键和字符串,它作为值位于元素内部。遗憾的是,转换元素集合没有共享的根元素,然后可以将其别名化为Map实例。使用Collections有addImplicitCollection方法可以解决这个问题,对于Maps有没有相应的解决方案?
有一段代码可以更准确地解释我想要实现的目标:
import com.thoughtworks.xstream.XStream;
import java.io.FileNotFoundException;
import java.util.Map;
import static org.junit.Assert.*;
import org.junit.Test;
public class XStreamMapDeserializationTest {
public static class Entry {
private String id;
Map<String, Translation> translations;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Map<String, Translation> getTranslations() {
return translations;
}
public void setTranslations(Map<String, Translation> translations) {
this.translations = translations;
}
}
public static class Translation {
private String id;
private String text;
public String getId() {
return id;
}
public String getText() {
return text;
}
public void setId(String id) {
this.id = id;
}
public void setText(String text) {
this.text = text;
}
}
@Test
public void testUnmarshall_shouldProperlyUnmarshallSingleEntry() {
//given
String xmlToUnmarshall
= "<entry id=\"0\">\n"
+ " <translation id=\"0\">\n"
+ " <text>autumn</text>\n"
+ " </translation>\n"
+ " <translation id=\"1\">\n"
+ " <text>der Herbst</text>\n"
+ " </translation>\n"
+ "</entry>";
XStream xstream = new XStream();
xstream.alias("entry", Entry.class);
xstream.alias("translation", Translation.class);
//when
Entry result = (Entry) xstream.fromXML(xmlToUnmarshall);
//then
assertNotNull("Entry should not be equal null", result);
}
}
答案 0 :(得分:0)
我最终为Entry类实现了转换器,每次它找到转换节点时它反序列化它并添加到map中,并在最后集中创建Map作为Entry字段。
class EntryConverter implements Converter {
@Override
public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
Entry entry = new Entry();
Map<String, Translation> translations = new HashMap<>();
while (reader.hasMoreChildren()) {
reader.moveDown();
String nodeName = reader.getNodeName();
if ("translation".equalsIgnoreCase(nodeName)) {
String id = reader.getAttribute("id");
Translation translation = (Translation) context.convertAnother(null, Translation.class);
translations.put(id, translation);
}
reader.moveUp();
}
entry.setTranslations(translations);
return entry;
}
@Override
public boolean canConvert(Class type) {
return Entry.class.isAssignableFrom(type);
}
}
然后我刚刚将转换器添加到xstream配置中:
xstream.registerConverter(new EntryConverter());