codecamp

Map节点的名称变更

Map节点的名称变更

改造需要的代码量比较多,因为JAXB原生不指定Map的自定义操作。也可以说JAXB不支持Map这种数据类型。所以需要使用到适配器来扩展Jaxb的功能。

首先定义一个类,其中只有两个字段,为了简单,可以不写setters/getters方法。通过这种方式模拟一个Map,只包含key/value,也就是first/second,这个名称就是XML的节点显示名称。

public class XmlMap {


    public String first;
    public String second;
}

自定义一个Adapter,这里将所有的代码都展示出来。

public class MapAdapter extends XmlAdapter<XmlMap[], Map<String, String>>{
    @Override
    public Map<String, String> unmarshal(XmlMap[] v) throws Exception {
        Map<String, String> map = new HashMap<>();
        for(int i=0;i<v.length;i++) {
            XmlMap pairs = v[i];
            map.put(pairs.first, pairs.second);
        }
        return map;
    }
    @Override
    public XmlMap[] marshal(Map<String, String> v) throws Exception {
        XmlMap[] xmlMap = new XmlMap[v.size()];
        int index = 0;
        for(Map.Entry<String, String> entry: v.entrySet()) {
            XmlMap xm = new XmlMap();
            xm.first = entry.getKey();
            xm.second = entry.getValue();
            xmlMap[index++] = xm;
        }
        return xmlMap;
    }
}

@XmlJavaTypeAdapterJAXB能够内置支持List和Set集合,但是对于Map的支持需要自己处理。它继承自抽象类XmlAdapter<ValueType,BoundType> 类型参数:

  • BoundType JAXB 不知道如何处理的一些类型。自定义的类型,告诉Jaxb ValueType 将此类型用作内存表示形式。
  • ValueType JAXB 无需其他操作便知道如何处理的类型。

这里的Map对于JAXB是一个未知类型,但是XmlMap[]却是已知的对象数组类型。通过中间的转化赋值,可以使XmlMap[]Map相互转化,从而让Jaxb知道数据如何处理。

在之前的Product中,在Map上加上注解@XmlJavaTypeAdapter(MapAdapter.class)

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Product2 {


    private String id;


    @XmlJavaTypeAdapter(MapAdapter.class)
    public Map<String, String> category;
//  setters, getters

测试一下:

@Test 
    public void test2() throws JAXBException {
        Map<String, String> map = new HashMap<>();
        map.put("衣服", "大衣");
        map.put("裤子", "西裤");
        Product2 product = new Product2();
        product.setId("1402");
        product.setCategory(map);

        
        JAXB.marshal(product, System.out);
    }

得到的结果:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<product2>
    <id>1402</id>
    <category>
        <item>
            <first>衣服</first>
            <second>大衣</second>
        </item>
        <item>
            <first>裤子</first>
            <second>西裤</second>
        </item>
    </category>
</product2>

上面的所有节点名称除了item都是可以通过一定的方法改变的。

使用注解 @XmlList
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

JAXB 简单转化案例

JAXB 之 Trang

简单XML生成——Marshaller数据源

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }