Results 1 to 4 of 4

Thread: XStreamMarshaller tweak for list of maps

  1. #1

    Default XStreamMarshaller tweak for list of maps

    Hello Everyone,

    I've run into a problem that I hope someone can help me with. I've searched high and low and have been unable to find an adequate solution.

    I'd like to take an ArrayList that is composed of Maps and convert it to XML.

    The ArrayList is defined like this: ArrayList<Map<String,String>>(). This list eventually gets put into a model to be displayed in a variety of formats:
    model.addAttribute("rows", ...ArrayList<Map<String,String>>...);

    A snippet of the servlet.xml file looks like this:

    ...
    <bean class="org.springframework.web.servlet.view.xml.Ma rshallingView">
    <constructor-arg>
    <bean class="org.springframework.oxm.xstream.XStreamMars haller" />
    </bean>
    </constructor-arg>
    <property name="modelKey" value="rows" />
    </bean>
    ...

    The output that I get from the listing about is the following:
    ....
    <map>
    <entry>
    <string>LineType</string>
    <string>DTL</string>
    </entry>
    <entry>
    <string>ClientCode</string>
    <string>000001</string>
    </entry>
    <entry>
    <string>ClientDescription</string>
    <string>TEST ACCOUNT - BOISE</string>
    </entry>
    <entry>
    <string>LineNumber</string>
    <string>1</string>
    </entry>
    </map>
    ...

    I'd rather the output look like this:
    ....

    <map>
    <LineType>DTL</LineType>
    <ClientCode>000001</ClientCode>
    <ClientDescription>TEST ACCOUNT - BOISE</ClientDescription>
    <LineNumber>1</LineNumber>
    </map>
    ...

    I basically want the Marshaller to use the map key (i.e. LineType) as the XML tag (i.e. <LineType>) and the map value as the content in opening and closing tags (i.e. DTL).

    For some reason I half expected that to be the default way XStreamMarshaller would work out of the box.

    Does anyone have some ideas to help make this happen? I was thinking that I could write a converter however, I didn't find any good examples for how to do that and I didn't know that was the purpose of a converter.

    Thanks for your help.

    Ranger.

  2. #2

    Default

    I am also looking for the same.Have you got the solution?

  3. #3

    Default

    Yes, we need to write custom convertor to get the data as map.
    Implement the Converter interface and provide custom logic in the

    public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context)
    {
    Map map = new HashMap<String, String> ();
    populateMap(reader, context, map);
    return map;
    }

    private void populateMap(HierarchicalStreamReader reader, UnmarshallingContext context, Map map)
    {
    for(; reader.hasMoreChildren(); reader.moveUp())
    {
    reader.moveDown();
    String key = reader.getNodeName();
    String value = reader.getValue();
    map.put(key, value);
    }

    }

    The above snippet of code will work for you.

  4. #4

    Default XStreamMarshaller that worked for me

    Thanks for your reply. That got me thinking about what I needed to do.

    This is what worked for me:

    public class XMLMapConverter implements Converter {
    public Object unmarshal(HierarchicalStreamReader reader,
    UnmarshallingContext context) {
    Map<String, String> map = new HashMap<String, String> ();
    populateMap(reader, context, map);
    return map;
    }

    private void populateMap(HierarchicalStreamReader reader,
    UnmarshallingContext context, Map<String, String> map) {
    for(; reader.hasMoreChildren(); reader.moveUp()) {
    reader.moveDown();
    String key = reader.getNodeName();
    String value = reader.getValue();
    map.put(key, value);
    }
    }

    public void marshal(Object source, HierarchicalStreamWriter writer,
    MarshallingContext context) {
    ArrayList<HashMap<String,String>> data = (ArrayList<HashMap<String,String>>) source;
    for(HashMap<String,String> map : data) {
    writer.startNode("row");
    for (Map.Entry<String, String> e : map.entrySet()) {
    writer.startNode(e.getKey());
    writer.setValue(e.getValue());
    writer.endNode();
    }
    writer.endNode();
    }
    }

    public boolean canConvert(Class type) {
    // TODO Auto-generated method stub
    return true;
    }
    }

    I then included the following bean config inside the
    <property name="defaultViews"> list.


    <bean class="org.springframework.web.servlet.view.xml.Ma rshallingView">
    <constructor-arg>
    <bean class="org.springframework.oxm.xstream.XStreamMars haller">
    <property name="converters">
    <list>
    <bean class="converters.XMLMapConverter"/>
    </list>
    </property>
    </bean>
    </constructor-arg>
    <property name="modelKey" value="rows" />
    </bean>

    I hope that helps someone.

    Ranger.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •