Search code examples
xmlhashmapxstreamconcurrenthashmaplinkedhashmap

Not able to override the root element while converting a LinkedHashMap and ConcurrentHashMap Object to xml using XStream()


I am trying to convert map objects (HashMap, LinkedHashMap and ConcurrentHashMap) to xml String using XStream() API. While converting the HashMap I am able to convert my map to xml with my desired root element by setting the alias like convertApi.alias("desired-root",Map.class);

Whereas while converting a LinkedHashMap or a ConcurrentHashMap I am not getting the desired-root for my xml, getting overridden like "linked-hash-map" or "concurrent-hash-map" respectively

Kindly help me in getting the desired root while using the linkedhashmap or ConcurrentHashMap. Thanks in advance :)

Code:

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;

import java.util.AbstractMap;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

public class Mapping {
    public static void main(String[] args) {

    Map<String,String> mp=new LinkedHashMap<String, String>();

    //Map contains: EmpId,Name
    mp.put("197","Deepak kumar modi");
    mp.put("198","Sweep panorama");
    mp.put("199","HD Video");
    mp.put("200","My Motorola Mobile");
    //System.out.println(mp);

    XStream magicApi = new XStream();
    magicApi.alias("root", Map.class);
    magicApi.registerConverter(new MapEntryConverter());

    String xml = magicApi.toXML(mp);
    System.out.println("Result of newly formed Xml:");
    System.out.println(xml);

}

private static class MapEntryConverter implements Converter{

    public void marshal(Object value, HierarchicalStreamWriter hierarchicalStreamWriter, MarshallingContext marshallingContext) {
        AbstractMap map = (AbstractMap) value;
        for (Object obj : map.entrySet()) {
            Map.Entry entry = (Map.Entry) obj;
            hierarchicalStreamWriter.startNode(entry.getKey().toString());
            hierarchicalStreamWriter.setValue(entry.getValue().toString());
            hierarchicalStreamWriter.endNode();
        }
    }

    public Object unmarshal(HierarchicalStreamReader hierarchicalStreamReader, UnmarshallingContext unmarshallingContext) {
        Map<String, String> map = new HashMap<String, String>();
        while(hierarchicalStreamReader.hasMoreChildren()) {
            hierarchicalStreamReader.moveDown();
            map.put(hierarchicalStreamReader.getNodeName(), hierarchicalStreamReader.getValue());
            hierarchicalStreamReader.moveUp();
        }
        return map;
    }

    public boolean canConvert(Class aClass) {
        return AbstractMap.class.isAssignableFrom(aClass);
    }
}

}

Output:

Result of newly formed Xml:
<linked-hash-map>
  <197>Deepak kumar modi</197>
  <198>Sweep panorama</198>
  <199>HD Video</199>
  <200>My Motorola Mobile</200>
</linked-hash-map>

Solution

  • XStream magicApi = new XStream();
    magicApi.alias("root", LinkedHashMap.class);
    

    Try this.