我正在使用SimpleXml。
我反序列化的xml看起来大致如此:
<?xml version="1.0" encoding="UTF-8"?>
<test a="1" e="2" f="5"/>
属性恰好是a
,e
和f
在运行时未知 - 可能同样是q
和z
。< / p>
班级定义:
@Root (strict = false)
public class Test {
@ElementMap (entry = "test", attribute = true)
public HashMap<String, Integer> map;
}
我希望Test.map
在反序列化后包含"a" -> 1
,"b" -> 2
和"f" -> 5
。
相反,我继续获得例外:unnable to satisfy @org.simpleframework.xml.ElementMap ... on field 'map' ... for class Test ...
(删除了绒毛 - 异常消息不包含任何进一步的说明)。
我试图摆弄ElementMap
的各种属性(内联,而不是内联等),但到目前为止还没有成功。
(实际情况是这些值恰好是数字的,虽然这是值得的,但如果必要的话,我可以自己解析它们的字符串值。不确定这里是否重要。)
解决方案是什么?
如果SimpleXml
没有提供任何开箱即用,那么建议的解决方法是什么?
答案 0 :(得分:2)
我使用Converter解决了这个问题,它允许手动执行反序列化。
所以现在的模型是:
public class Test {
@Convert (MapConverter.class)
@Element (name = "test")
public HashMap<String, Integer> test;
}
MapConverter
:
public class MapConverter implements Converter<HashMap<String, Integer>> {
@Override
public HashMap<String, Integer> read(InputNode inputNode) throws Exception {
final HashMap<String, Integer> result = new HashMap<String, Integer>();
for (final String attributeName : inputNode.getAttributes()) {
final String value = inputNode.getAttribute(attributeName).getValue();
result.put(attributeName, Integer.parseInt(value));
}
return result;
}
@Override
public void write(OutputNode outputNode, HashMap<String, Integer> stringIntegerHashMap)
throws Exception {
// not used
}
}
请注意,要实现此目的,您必须将AnnotationStrategy
的实例传递给Persister
:
// instead of new Persister()
Persister persister = new Persister(new AnnotationStrategy());
我不喜欢这个解决方案,因为
我怀疑这可能是一种矫枉过正的
初始化Persister
是在我必须使用的预先存在的库中进行的,所以它要求我打开代码以使其完全正常工作。
Persister
默认忽略框架的本机注释之一这一事实会导致混淆的API(即使记录了此行为)。但那是一个不同的故事。
我想知道是否有人想出更好的东西。