4

HashMapを使用してフィールドのXML表現を適応させたいXmlAdapter。私はそれを行うためにを使用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>
4

1 に答える 1

2

を に直接変換するのではなく、プロパティを持つオブジェクトのインスタンスにXmlAdapter変換する必要があります。HashMapListArrayList

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;
        }
    }

}

詳細については


アップデート

ありがとう、これはうまくいきます。ただし、生成された XML で追加のレベルの注釈を取得します。それを回避する方法はありますか?

EclipseLink MOXyJAXB (JSR-222)プロバイダーとして使用している場合は、このユース ケースの拡張機能を利用できます@XmlPath。以下に例を挙げて説明します。

フー

hashmapプロパティに加えて、MOXy@XmlJavaTypeAdapter@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/05/specifying-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/出力

以下は、デモ コードの実行に対する入力と出力です。

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

詳細については

于 2012-10-31T17:37:24.453 に答える