如何使用SimpleXml将xml反序列化为自定义属性(及其值)的映射?

时间:2014-09-21 17:38:47

标签: java xml xml-serialization simple-framework

我正在使用SimpleXml

我反序列化的xml看起来大致如此:

<?xml version="1.0" encoding="UTF-8"?> 
<test a="1" e="2" f="5"/>

属性恰好是aef在运行时未知 - 可能同样是qz。< / 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没有提供任何开箱即用,那么建议的解决方法是什么?

1 个答案:

答案 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()); 

我不喜欢这个解决方案,因为

  1. 我怀疑这可能是一种矫枉过正的

  2. 初始化Persister是在我必须使用的预先存在的库中进行的,所以它要求我打开代码以使其完全正常工作。

  3. Persister默认忽略框架的本机注释之一这一事实会导致混淆的API(即使记录了此行为)。但那是一个不同的故事。

    我想知道是否有人想出更好的东西。