JAXB: Как подавить окружающий XmlElement при использовании XmlJavaTypeAdapter?

я использую@XmlJavaTypeAdapter преобразовыватьMap объекты вList при сортировке (и наоборот при отмене сортировки)

В списке всегда есть окружение@XmlElement и я хочу избавиться от него, поскольку он загромождает итоговый XML.

Как это может быть сделано?

Или, другими словами, как я могу избавиться от стихииmap в следующем XML:



    
        
    

Учебный классMapItemпростой класс с ключом и значением:

public static class MapItem {
    @XmlAttribute(name = "key")
    String key;

    @XmlAttribute(name = "val")
    String val;
}

ДекларацияMap либо неявно, либо явно содержит@XmlElement аннотация:

@XmlJavaTypeAdapter(MyMapItemAdapter.class)
@XmlElement(name = "map")
Map map = new TreeMap();

Классы для:@XmlJavaTypeAdapter

@XmlType(name = "map-type", propOrder = { "list" })
static class MyMapItemType {
    @XmlElement(name = "item")
    List list = new ArrayList();
}

@XmlTransient
static final class MyMapItemAdapter extends
        XmlAdapter {

    MyMapItemAdapter() {
    }

    @Override
    public MyMapItemType marshal(Map arg0)
            throws Exception {
        MyMapItemType myMapType = new MyMapItemType();
        for (Entry entry : arg0.entrySet()) {
            myMapType.list.add(entry.getValue());
        }
        return myMapType;
    }

    @Override
    public Map unmarshal(MyMapItemType arg0)
            throws Exception {
        TreeMap treeMap = new TreeMap();
        for (MapItem myEntryType : arg0.list) {
            treeMap.put(myEntryType.key, myEntryType);
        }
        return treeMap;
    }
}

Объявление высшего класса:

@XmlRootElement(name = "top")
@XmlType(name = "top")
@XmlAccessorType(XmlAccessType.FIELD)
public class JaxbMapTest {

Мой полный тестовый класс:

package xml;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.Map.Entry;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlRootElement(name = "top")
@XmlType(name = "top")
@XmlAccessorType(XmlAccessType.FIELD)
public class JaxbMapTest {

    public static class MapItem {
        @XmlAttribute(name = "key")
        String key;

        @XmlAttribute(name = "val")
        String val;
    }

    @XmlTransient
    static final class MyMapItemAdapter extends
            XmlAdapter {

        MyMapItemAdapter() {
        }

        @Override
        public MyMapItemType marshal(Map arg0)
                throws Exception {
            MyMapItemType myMapType = new MyMapItemType();
            for (Entry entry : arg0.entrySet()) {
                myMapType.list.add(entry.getValue());
            }
            return myMapType;
        }

        @Override
        public Map unmarshal(MyMapItemType arg0)
                throws Exception {
            TreeMap treeMap = new TreeMap();
            for (MapItem myEntryType : arg0.list) {
                treeMap.put(myEntryType.key, myEntryType);
            }
            return treeMap;
        }
    }

    @XmlType(name = "map-type", propOrder = { "list" })
    static class MyMapItemType {
        @XmlElement(name = "item")
        List list = new ArrayList();
    }

    public static void main(String[] args) {

        try {

            // Setup object
            JaxbMapTest jaxbMapTest = new JaxbMapTest();
            MapItem mapItem = new MapItem();
            mapItem.key = "some-key";
            mapItem.val = "some-val";
            jaxbMapTest.add(mapItem);

            // Marshal
            JAXBContext jaxbContext = JAXBContext
                    .newInstance(JaxbMapTest.class);
            Marshaller marshaller = jaxbContext.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
                    Boolean.TRUE);
            marshaller.marshal(jaxbMapTest, new File("JaxbMapTest.out"));

            // Exit
            System.exit(0);
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

    @XmlJavaTypeAdapter(MyMapItemAdapter.class)
    @XmlElement(name = "map")
    Map map = new TreeMap();

    void add(MapItem mapItem) {
        map.put(mapItem.key, mapItem);
    }
}

Ответы на вопрос(1)

Решение Вопроса

Примечание: ямEclipseLink JAXB (МОКСИ) привести и членJAXB (JSR-222) экспертная группа.

Вы могли бы использовать@XmlPath(".") расширение в MOXy для отображения этого варианта использования. Определение"." поскольку путь указывает, что содержимое дочернего элемента должно быть записано в элемент родительских объектов.

import java.util.HashMap;
import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.eclipse.persistence.oxm.annotations.XmlPath;

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

    @XmlJavaTypeAdapter(MyMapItemAdapter.class)
    @XmlPath(".")
    Map map = new TreeMap();       

}

Полный пример

JAXB маршал ArrayList, созданный XmlAdapter

Для дополнительной информации

http://blog.bdoughan.com/2010/07/xpath-based-mapping.htmlhttp://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html
 Vincenzo Z02 нояб. 2012 г., 12:46
Спасибо за предложение, буду иметь в виду. Ничего против МОКСИ, но было бы неплохо иметь стандартное решение. Я также рассмотрел использованиеSet (сHashSet или жеTreeSet) но ничья есть, что я 'Я должен найти приемлемую альтернативу дляAbstractMap.get(), (Кстати, общее спасибо за ваши сообщения, которые я часто читаю и которые я очень ценю!)

Ваш ответ на вопрос