java - JAXB @ XmlAdapter: मानचित्र-> सूची एडाप्टर?(मार्शल केवल)



marshalling moxy (1)

किसी List में Map को आदत डाल देने के बजाय, आपको इसे उस ऑब्जेक्ट में अनुकूलित करना चाहिए जिसमें एक List संपत्ति है।

एक्सएमएलएडैप्टर (मैपप्रॉपर्टीजएडैप्टर)

import java.util.*;
import java.util.Map.Entry;
import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlAdapter;

public class MapPropertiesAdapter extends XmlAdapter<MapPropertiesAdapter.AdaptedProperties, Map<String, String>>{

    public static class AdaptedProperties {
        public List<Property> property = new ArrayList<Property>();
    }

    public static class Property {
        @XmlAttribute
        public String name;

        @XmlValue
        public String value;
    }

    @Override
    public Map<String, String> unmarshal(AdaptedProperties adaptedProperties) throws Exception {
        if(null == adaptedProperties) {
            return null;
        }
        Map<String, String> map = new HashMap<String, String>(adaptedProperties.property.size());
        for(Property property : adaptedProperties.property) {
            map.put(property.name, property.value);
        }
        return map;
    }

    @Override
    public AdaptedProperties marshal(Map<String, String> map) throws Exception {
        if(null == map) {
            return null;
        }
        AdaptedProperties adaptedProperties = new AdaptedProperties();
        for(Entry<String,String> entry : map.entrySet()) {
            Property property = new Property();
            property.name = entry.getKey();
            property.value = entry.getValue();
            adaptedProperties.property.add(property);
        }
        return adaptedProperties;
    }

}

डोमेन मॉडल (रूट)

नीचे एक Map संपत्ति के साथ एक मॉडल वस्तु है @XmlJavaTypeAdapter एनोटेशन @XmlJavaTypeAdapter को निर्दिष्ट करने के लिए उपयोग किया जाता है।

import java.util.Map;
import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

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

    @XmlJavaTypeAdapter(MapPropertiesAdapter.class)
    private Map<String, String> properties;

}

डेमो

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

public class Demo {

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

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum17024050/input.xml");
        Root root = (Root) unmarshaller.unmarshal(xml);

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

}

input.xml / आउटपुट

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <properties>
        <property name="A">a</property>
        <property name="B">b</property>
    </properties>
</root>

मेरे पास एक Map<String, String>
पहला विचार हर किसी को यह List<Pair<String,String>> (एक कस्टम वर्ग होने के नाते) में परिवर्तित करना है।

मैंने इस तरह एक @XmlAdapter की कोशिश की है:

public class MapPropertiesAdapter extends XmlAdapter<List<Property>, Map<String,String>> { ... }

लेकिन एलेप्से मोक्सी, जेएसीएबी का उपयोग मैं एक क्लास क्लास्ट एक्सपैशन के साथ समाप्त कर रहा हूं- "हाशमैप कलेक्शन को परिवर्तित नहीं किया जा सकता"।

क्या यह रूपांतरण JAXB द्वारा समर्थित है? या मैंने कुछ दस्तावेज भाग को अनदेखा किया है जो बताता है कि ऐसा क्यों नहीं है?

पुनश्च: मैं इस तरह XML प्राप्त करना चाहता था:

<properties>
    <property name="protocol"/>
    <property name="marshaller"/>
    <property name="unmarshaller"/>
    <property name="timeout"/>
    ...
</properties>

मुझे मिल गया, केवल एक इंटरमीडिएट वर्ग का उपयोग करना था साथ ही XMLCompositeObjectMappingNodeValue.marshalSingleValue (XMLCompositeObjectMappingNodeValue.java:161) में हैंडल एनपीई में वर्णित है





xmladapter