Проблемы составления карты в Jaxb - PullRequest
2 голосов
/ 17 октября 2011

У меня есть класс мир , который содержит карту людей. Если я маршал мир классов, я получаю следующий вывод:

<world>
    <humans>
        <human key="2">
            <value>
                <name>Tom</name>
            </value>
        </human>
        <human key="1">
            <value>
                <name>Max</name>
            </value>
        </human>
    </humans>
</world>

Но я не хочу отображать «значение» -Tag. Это должно выглядеть так:

<world>
    <humans>
        <human key="2">
            <name>Tom</name>
        </human>
        <human key="1">
            <name>Max</name>
        </human>
    </humans>
</world>

Возможно ли это?

Вот код класса мир и человек:

@XmlRootElement
public class Human {

    @XmlElement
    private String name;

    public Human(){}
}

@XmlRootElement
public class World {

    private Map<String, Human> humans = new HashMap<String, Human>();

    public World(){}

    @XmlElementWrapper( name = "humans")
    @XmlElement(name = "human")
    public HumanEntry[] getMap() {
        List<HumanEntry> list = new ArrayList<HumanEntry>();
        for (Entry<String, Human> entry : humans.entrySet()) {
            HumanEntry mapEntry =new HumanEntry();
            mapEntry.key = entry.getKey();
            mapEntry.value = entry.getValue();
            list.add(mapEntry);
        }
        return list.toArray(new HumanEntry[list.size()]);
    }

    public void setMap(HumanEntry[] arr) {
        for(HumanEntry entry : arr) {
            this.humans.put(entry.key, entry.value);
        }
    }

    public static class HumanEntry {
        @XmlAttribute
        public String key;

        @XmlElement
        public Human value;
    }

    public void addHuman(String key, Human human){
        this.humans.put(key, human);
    }
}

Ответы [ 3 ]

2 голосов
/ 17 октября 2011

Как было указано ilcavero , XmlAdapter можно использовать для применения альтернативного отображения к карте (или любому другому типу) в JAXB. Ниже приведена ссылка на конкретный пример:

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

2 голосов
/ 18 октября 2011

Мое решение

Я добавил ключевой атрибут для человека, а затем преобразовал карту в массив:

@XmlRootElement
public class World {

    @XmlJavaTypeAdapter(HumanAdapter.class)
    private Map<String, Human> humans = new HashMap<String, Human>();

    public World(){}
}

public class Human {

    @XmlElement
    private String name;

    @XmlAttribute(name="key")
    private String key;

    public Human(){}
}

public class HumanAdapter extends XmlAdapter<HumanJaxbCrutch, Map<String, Human>> {

    @Override
    public HumanJaxbCrutch marshal(Map<String, Human> humans) throws Exception {
        List<Human> list = new ArrayList<Human>();
        for (Entry<String, Human> entry : humans.entrySet()) {
            list.add(entry.getValue());
        }

        HumanJaxbCrutch humanJaxbCrutch = new HumanJaxbCrutch();
        humanJaxbCrutch.setCourses(list.toArray(new Human[list.size()])); 

        return humanJaxbCrutch;
    }

    @Override
    public Map<String, Human> unmarshal(HumanJaxbCrutch humans) throws Exception {
        Map<String, Human> map = new HashMap<String, Human>();

        for(Human human : humans.getCourses()){
            map.put(human.getKey(), human);
        }

        return map;
    }
}

class HumanJaxbCrutch {

    private Human[] courses;

    @XmlElement(name = "human")
    public Human[] getCourses() {
        return courses;
    }

    public void setCourses(Human[] courses) {
        this.courses = courses;
    }
}
1 голос
/ 17 октября 2011

Я думаю, что вы ищете аннотацию XmlValue: http://jaxb.java.net/tutorial/section_6_2_7_4-Mapping-a-Class-to-Simple-Content-or-Simple-Type-XmlValue.html#Mapping%20a%20Class%20to%20Simple%20Content%20or%20Simple%20Type:%20XmlValue

В вашем случае она будет применяться к HumanEntry.value вместо XmlElement

...