如何使用 SimpleXml 将 xml 反序列化为自定义属性(及其值)的映射? [英] How to deserialize xml into a map of custom attributes (and their values) with SimpleXml?

查看:16
本文介绍了如何使用 SimpleXml 将 xml 反序列化为自定义属性(及其值)的映射?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 SimpleXml.

我正在反序列化的 xml 大致如下所示:

The xml I am deserializing looks roughly like so:

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

属性恰好是 aef 在运行时是未知的 - 可能是 qz 也一样.

That the attributes happen to be a, e and f is not known at runtime - could be q and z just as well.

类定义:

@Root (strict = false)
public class Test {
   @ElementMap (entry = "test", attribute = true)
   public HashMap<String, Integer> map;
}

我希望 Test.map 包含 "a" ->1, "b" ->2"f" ->5 反序列化后.

I expect Test.map to contain "a" -> 1, "b" -> 2 and "f" -> 5 after deserialization.

相反,我不断收到异常:无法满足@org.simpleframework.xml.ElementMap ... on field 'map' ... for class Test ...(去除绒毛- 异常消息不包含任何进一步的说明).

Instead, I keep on getting an exception: unnable to satisfy @org.simpleframework.xml.ElementMap ... on field 'map' ... for class Test ... (fluff removed - exception message doesn't contain any further clarification).

我试图摆弄 ElementMap 的各种属性(内联,不内联等),但到目前为止没有成功.

I tried to fiddle with various attributes of ElementMap (inlining, not inlining etc.), but to no success so far.

(实际上,这些值碰巧是数字,尽管这是间接的,如果有必要,我可以使用字符串值自行解析它们——但不确定这里是否重要.)

(It is actually the case that the values happen to be numeric, although that's circumstantial and I'd be fine going with string values to parse them on my own if that's necessary - not sure if it matters at all here though.)

解决办法是什么?

如果 SimpleXml 没有提供任何现成的,建议的解决方法是什么?

And if SimpleXml doesn't offer any out of the box, what's the suggested workaround?

推荐答案

我使用 Converter,允许手动执行反序列化.

I solved it with the use of a Converter, which allows to perform the deserialization manually.

所以现在模型是:

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:

Note that for this to work you have to pass an instance of AnnotationStrategy to Persister:

// instead of new Persister()
Persister persister = new Persister(new AnnotationStrategy()); 

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

I'm not that keen on this solution, because

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

  1. I suspect it could be an overkill

初始化 Persister 是在我必须使用的预先存在的库的深处完成的,所以它需要我破解代码才能让它工作.

Initializing a Persister is done deep inside a preexisting library that I have to be using, so it required me to crack the code open in order to get it to work at all.

事实上,Persister 默认忽略框架的本机注释之一,这会导致 API 混乱(即使记录了此行为).但那是另一回事了.

The fact that Persister ignores one of the framework's native annotation by default makes for a confusing API (even though this behaviour is documented). But that's a different story.

我想知道是否有人想出了更好的方法.

I wonder if someone comes up with something better.

这篇关于如何使用 SimpleXml 将 xml 反序列化为自定义属性(及其值)的映射?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆