java - 使用 Java XML 注释、JAXB 绑定(bind)多个元素以将属性作为键进行映射

标签 java xml map jaxb unmarshalling

我有一个 XML 源,我从中使用 JAXB 解码对象。 XML 来源:

<album>
    <name>something</name>
    <id>003030</id>
    <artist>someone</artist>
    ...
</album>

Java 源代码是这样的(还有所需的 getter/setter):

@XmlRootElement(name="album")
class Album {
    String name;
    Long id;
    String artist;
    ...
}

到目前为止一切顺利。现在我在相册列表中得到了一些不同大小的图片 url:

...
<image size="small">http://.../small.jpg</image>
<image size="medium">http://.../medium.jpg</image>
<image size="large">http://.../large.jpg</image>
...

我想将它映射到像这样的 java Map:

Map<String,String> imageUrls;

map 的键是大小属性, map 的值是元素值。 如果可能的话,我应该如何注释这个变量?

最佳答案

辅助类 Pair

@XmlAccessorType(XmlAccessType.FIELD)
public class Pair {

    @XmlAttribute
    private String key;

    @XmlValue
    private String value;

    public Pair() {
    }

    public Pair(String key, String value) {
        this.key = key;
        this.value = value;
    }  
//... getters, setters  
}  

对列表

@XmlAccessorType(XmlAccessType.FIELD)
public class PairList 
{
    private List<Pair> values = new ArrayList<Pair>();

    public PairList() {
    }  
//...  
}  

适配器

public class MapAdaptor extends XmlAdapter<PairList, Map<String, String>> 
{
    @Override
    public Map<String, String> unmarshal(PairList list) throws Exception 
    {
        Map<String, String> retVal = new HashMap<String, String>();
        for (Pair keyValue : list.getValues()) 
        {
            retVal.put(keyValue.getKey(), keyValue.getValue());
        }
        return retVal;
    }

    @Override
    public PairList marshal(Map<String, String> map) throws Exception 
    {
        PairList retVal = new PairList();
        for (String key : map.keySet()) 
        {
            retVal.getValues().add(new Pair(key, map.get(key)));
        }
        return retVal;
    }
}

在你的实体中的使用

@XmlJavaTypeAdapter(value = MapAdaptor.class)
private Map<String, String> imageUrls = new HashMap<String, String>();  

附言
你可以不用课 PairList使用 Pair[]而不是 PairList
适配器

public class MapAdaptor extends XmlAdapter<Pair[], Map<String, String>> 
{
    @Override
    public Map<String, String> unmarshal(Pair[] list) throws Exception 
    {
        Map<String, String> retVal = new HashMap<String, String>();
        for (Pair keyValue : Arrays.asList(list)) 
        {
            retVal.put(keyValue.getKey(), keyValue.getValue());
        }
        return retVal;
    }

    @Override
    public Pair[] marshal(Map<String, String> map) throws Exception 
    {
        List<Pair> retVal = new ArrayList<Pair>();
        for (String key : map.keySet()) 
        {
            retVal.add(new Pair(key, map.get(key)));
        }
        return retVal.toArray(new Pair[]{});
    }
}  

但在这种情况下,您无法控制每一对的名称。它将是 item 并且您无法更改它

<item key="key2">valu2</item>
<item key="key1">valu1</item>  

PS2
如果您尝试使用 List<Pair>而不是 PairList , 你会得到 Exception

ERROR: java.util.List haven't no-arg constructor

关于java - 使用 Java XML 注释、JAXB 绑定(bind)多个元素以将属性作为键进行映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12287859/

相关文章:

java - XML 属性值规范化 - 应如何处理实体中的空格?

c# - 将 powershell 对象另存为 xml 并在 c# 中加载

java - 我需要将 XML 文件附加到在 Java 7 中使用 SAAJ 的 SOAP 对象

java - 如何使用 JPA 存储 Map<String, List<String>>

java - 如何制作绘制线条的 Java 程序?

java - Spring 4 不会自动限定 Autowiring 上的泛型类型

Java正则表达式最长匹配

java - Mapreduce 编程 : details required

c++ - std::map.insert "could not deduce template argument for..."

java - 如何使用 jdk 1.7 和 spring 3.0.4 将 tomcat 应用服务器更改为版本 8?