使用@XmlJavaTypeAdapter映射Map时的JAXB和空命名空间

时间:2012-02-07 17:50:09

标签: java xml data-binding jaxb

我正在尝试使用JAXB和@XmlJavaTypeAdaptor在编组期间映射Map。我遇到的唯一问题是用于包含地图中每个条目的“item”元素被赋予空白名称空间。

以下是显示问题的生成XML文档示例:

<format xmlns="myNamespace">
    <data>
        <item xmlns:ns2="myNamespace" xmlns="">
            <ns2:key>Admin</ns2:key>
            <ns2:value>John</ns2:value>
        </item>
    </data>
</format>

我希望片段看起来像这样:

<format xmlns="myNamespace">
    <data>
        <item>
            <key>Admin</key>
            <value>John</value>
        </item>
    </data>
</format>

我简化了现实生活中的例子,将其缩小到这种情况。这是正在编组的课程:

@XmlRootElement(name = "format")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType
public final class Format {

    @XmlTransient
    private final Map<String, String> data = new HashMap<String, String>();

    @XmlJavaTypeAdapter(MapAdapter.class)
    public Map<String, String> getData() {
        return data;
    }
}

以下是我正在使用的XmlAdapter的实现:

public class MapAdapter extends XmlAdapter<MapElements[], Map<String, String>> {

    @Override
    public MapElements[] marshal(Map<String, String> stringStringMap) throws Exception {
        MapElements[] mapElements = new MapElements[stringStringMap.size()];
        int i = 0;

        for (Map.Entry<String, String> entry: stringStringMap.entrySet()) {
            mapElements[i++] = new MapElements(entry.getKey(), entry.getValue());
        }

        return mapElements;
    }

    @Override
    public Map<String, String> unmarshal(MapElements[] mapElements) throws Exception {
        Map<String, String> map = new HashMap<String, String>();

        for (MapElements mapElement : mapElements) {
            map.put(mapElement.key, mapElement.value);
        }

        return map;
    }
}

我像这样设置包级别信息,这确实有助于确保除“item”元素之外的所有元素的命名空间都具有命名空间“myNamespace”:

@XmlSchema(namespace = "myNamespace", elementFormDefault = XmlNsForm.QUALIFIED)
package org.prystasj;

import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;

我已尝试过每种注释组合,例如: @XmlElement(namespace =“myNamespace”),我可以一直想到并且没有机会,所以我认为我缺少一些概念性的东西(或者甚至可能是一些相当微不足道的东西)。

我正在使用JAXB 2.2.2。

提前感谢任何见解。

1 个答案:

答案 0 :(得分:2)

您可以对XmlAdapter

使用以下内容
import java.util.*;

import javax.xml.bind.annotation.adapters.XmlAdapter;

public class MapAdapter extends XmlAdapter<MapAdapter.MapElements, Map<String, String>> {

    @Override
    public MapElements marshal(Map<String, String> stringStringMap) throws Exception {
        MapElements mapElements = new MapElements();
        for (Map.Entry<String, String> entry: stringStringMap.entrySet()) {
            mapElements.item.add(new MapElement(entry.getKey(), entry.getValue()));
        }
        return mapElements;
    }

    @Override
    public Map<String, String> unmarshal(MapElements mapElements) throws Exception {
        Map<String, String> map = new HashMap<String, String>();
        for (MapElement mapElement : mapElements.item) {
            map.put(mapElement.key, mapElement.value);
        }
        return map;
    }

    public static class MapElements {
        public List<MapElement> item = new ArrayList<MapElement>();
    }

    public static class MapElement {
        public String key;
        public String value;

        public MapElement() {
        }

        public MapElement(String key, String value) {
            this.key = key;
            this.value = value;
        }

    }

}