XStream:不带容器节点的NamedMapConverter和HashMap

问题描述

我有以下java类

@XStreamAlias("object")
public class MyObject {

    @XStreamAsAttribute
    private String name;

    private Map<String,String> description = new HashMap<>();

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }

    public Map<String,String> getDescription() { return description; }
    public void setDescription(Map<String,String> description) { this.description = description; }
}

如何初始化XStream将其转换为以下XML(并解析XML以创建Java对象):

<?xml version="1.0" ?>
<object name="test">
  <description language="en">Test en</description>
  <description language="fr">Test fr</description>
</object>

我当然希望语言是我的描述Map的关键,而节点值是map的值。

我尝试过这个:

XStream xs = new XStream(new DomDriver());
xs.processAnnotations(MyObject.class);
xs.registerConverter(new NamedMapConverter(xs.getMapper(),"description","language",String.class,null,true,false,xs.getConverterLookup()));

但是我得到以下输出

<object name="name test">
  <description>
    <description language="en">Test en</description>
    <description language="fr">Test fr</description>
  </description>
</object>

如何摆脱容器标签

编辑:我想避免为整个MyObject类编写自定义转换器,因为真正的类有点复杂,当前,除了描述字段外,它没有自定义转换器就可以工作。类似于NamedMapConverter的东西会很棒。

解决方法

我不了解XStream,但是您可以使用SimpleXml来做到这一点。

public final class Question4 {

    @XmlName("object")
    public static class MyObject {
        @XmlAttribute
        private String name = "test";
        @XmlMapWithAttributes(keyName = "language")
        private Map<String,String> description = new HashMap<>();

        private MyObject() {
            description.put("en","Test en");
            description.put("fr","Test fr");
        }
    }

    public static void main(final String... args) {
        XmlParser parser = new XmlParser();
        System.out.println(parser.toXml(new MyObject()));
    }

}

您可以看到不需要配置解析器,只需将注释添加到字段中。输出将是这样:

<object name="test">
  <description language="en">Test en</description>
  <description language="fr">Test fr</description>
</object>