【问题标题】:JAXB and empty namespace when using @XmlJavaTypeAdapter to map a Map使用 @XmlJavaTypeAdapter 映射 Map 时的 JAXB 和空命名空间
【发布时间】:2012-02-07 17:50:08
【问题描述】:

我正在尝试使用 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。

提前感谢您提供任何见解。

【问题讨论】:

    标签: java xml data-binding jaxb


    【解决方案1】:

    您可以将以下内容用于您的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;
            }
    
        }
    
    }
    

    【讨论】:

    • 这成功了。您能否提供更多信息来说明为什么它确实可以做到这一点?再次感谢!
    • 我也对你的代码为什么能工作 Blaise 感兴趣。我有类似的问题,但无法让它工作。您能否就此分享一些见解?也许甚至这个问题的作者都知道缺少什么。任何帮助都是适当的。
    猜你喜欢
    • 2013-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-21
    • 2013-09-06
    相关资源
    最近更新 更多