Announcement Announcement Module
Collapse
No announcement yet.
XStreamMarshaller tweak for list of maps Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • 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
    I am also looking for the same.Have you got the solution?

    Comment


    • #3
      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.

      Comment


      • #4
        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.

        Comment

        Working...
        X