JAXB元帅由XMLADAPTER创建的阵列列表



我想使用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;
    }
}
public final class HashMapAdapter extends XmlAdapter<ArrayList<HashMapEntry>, HashMap<String, String>> {
    @Override
    public ArrayList<HashMapEntry> marshal(HashMap<String, String> arg0) throws Exception {
        ArrayList<HashMapEntry> result = new ArrayList<HashMapEntry>();
        for(Entry<String, String> entry : arg0.entrySet())
            result.add(new HashMapEntry(entry.getKey(), entry.getValue()));
        return result;
    }
    @Override
    public HashMap<String, String> unmarshal(ArrayList<HashMapEntry> arg0) throws Exception {
        HashMap<String, String> result = new HashMap<String, String>();
        for(HashMapEntry entry : arg0)
            result.put(entry.key, entry.value);
        return result;
    }
}
public class HashMapEntry {
    @XmlElement 
    public String key;
    @XmlValue
    public String value;
    public HashMapEntry() {
    }
    public HashMapEntry(String key, String value) {
        this.key = key;
        this.value = value;
    }
}

结果

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><hashmap/></foo>

在您的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;
        }
    }
}

有关更多信息

  • http://blog.bdoughan.com/2010/07/xmladapter-jaxbs-jaxbs-secret-weapon.html

update

谢谢,这有效。但是,我得到了一个额外的水平 产生的XML注释。有什么办法避免这种情况吗?

如果您正在使用 eclipselink moxy 作为您的 JAXB(JSR-222)提供商,则可以利用此用例的@XmlPath扩展名。我将在下面以示例演示。

foo

hashmap属性上,除了@XmlJavaTypeAdapter外,我还添加了Moxy的@XmlPath注释。"."的XML路径表明应该将孩子编造成父母XML元素。

package forum13163430;
import java.util.HashMap;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.eclipse.persistence.oxm.annotations.XmlPath;
@XmlRootElement
public class Foo {
    private HashMap<String, String> hashMap;
    public Foo() {
        this.hashMap = new HashMap<String, String>();
    }
    @XmlPath(".")
    @XmlJavaTypeAdapter(HashMapAdapter.class)
    public HashMap<String, String> getHashmap() {
        return hashMap;
    }
    public void setHashmap(HashMap<String, String> hashMap) {
        this.hashMap = hashMap;
    }
}

jaxb.properties

要将Moxy指定为JAXB提供商,您需要将一个称为jaxb.properties的文件包含在与您的域模型相同的包装中,请参见以下条目(请参阅:http://blog.bdoughan.com/2011/2011/05/specifying-epecifying-eclipselink-eclipselink-moxy-as-your.html)。

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

演示

由于Moxy是JAXB(JSR-222)合规性实现,因此标准API可用于将对象从/转换为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

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

<?xml version="1.0" encoding="UTF-8"?>
<foo>
   <item key="b">B</item>
   <item key="c">C</item>
   <item key="a">A</item>
</foo>

有关更多信息

  • http://blog.bdoughan.com/2010/07/xpath lase-mapping.html

最新更新