Java JAXB封送XmlAdapter创建的ArrayList

Java JAXB封送XmlAdapter创建的ArrayList,java,arraylist,jaxb,marshalling,xmladapter,Java,Arraylist,Jaxb,Marshalling,Xmladapter,我想使用XmlAdapter调整HashMap字段的XML表示。我使用ArrayList来实现这一点。但是,在编组时,根本不会编组ArrayList。为什么呢 代码 @XmlRootElement public class Foo { private HashMap<String, String> hashMap; public Foo() { this.hashMap = new HashMap<String, String>();

我想使用
XmlAdapter
调整
HashMap
字段的XML表示。我使用
ArrayList
来实现这一点。但是,在编组时,根本不会编组
ArrayList
。为什么呢

代码

@XmlRootElement
public class Foo {

    private HashMap<String, String> hashMap;

    public Foo() {
        this.hashMap = new HashMap<String, String>();
    }

    @XmlJavaTypeAdapter(HashMapAdapter.class)
    public HashMap<String, String> getHashmap() {
        return hashMap;
    }

    public void setHashmap(HashMap<String, String> hashMap) {
        this.hashMap = hashMap;
    }

}
结果


XmlAdapter
中,您需要将
HashMap
转换为具有
List
属性的对象实例,而不是直接转换为
ArrayList

HashMapAdapter

package forum13163430;

import java.util.*;
import java.util.Map.Entry;

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

public final class HashMapAdapter extends XmlAdapter<HashMapAdapter.AdaptedHashMap, HashMap<String, String>> {

    @Override
    public AdaptedHashMap marshal(HashMap<String, String> hashMap) throws Exception {
        AdaptedHashMap adaptedHashMap = new AdaptedHashMap();
        for(Entry<String, String> entry : hashMap.entrySet()) {
            adaptedHashMap.item.add(new HashMapEntry(entry.getKey(), entry.getValue()));
        }
        return adaptedHashMap;
    }

    @Override
    public HashMap<String, String> unmarshal(AdaptedHashMap adaptedHashMap) throws Exception {
        HashMap<String, String> result = new HashMap<String, String>();
        for(HashMapEntry entry : adaptedHashMap.item)
            result.put(entry.key, entry.value);
        return result;
    }

    public static class AdaptedHashMap {
        public List<HashMapEntry> item = new ArrayList<HashMapEntry>();
    }

    public static class HashMapEntry {

        @XmlAttribute 
        public String key;

        @XmlValue
        public String value;

        public HashMapEntry() {
        }

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

}
jaxb.properties

要将MOXy指定为JAXB提供程序,您需要在与域模型相同的包中包含一个名为
JAXB.properties
的文件,其中包含以下条目(请参阅:)

演示

由于MOXy是JAXB(JSR-222)兼容的实现,因此可以使用标准api将对象从XML转换为XML

package forum13163430;

import java.io.File;
import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Foo.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum13163430/input.xml");
        Foo foo = (Foo) unmarshaller.unmarshal(xml);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(foo, System.out);
    }

}
input.xml/Output

下面是运行演示代码的输入和输出


B
C
A.
了解更多信息


谢谢,这很有效。然而,随后我在生成的XML中得到了一个附加级别的注释。有什么办法可以避免吗?@hansi-我用一个例子更新了我的答案,说明如何利用EclipseLink JAXB(MOXy)的
@XmlPath
扩展来实现这一点。我是莫西领队。
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
package forum13163430;

import java.io.File;
import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Foo.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum13163430/input.xml");
        Foo foo = (Foo) unmarshaller.unmarshal(xml);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(foo, System.out);
    }

}