Hi Jorg,

Thanks a lot for your feedback. I will give it a try.

Cheers

Johann

On Wed, Sep 17, 2014 at 2:29 PM, Jörg Schaible <joerg.schai...@swisspost.com
> wrote:

> Hi Johann,
>
> sorry for the late response, but I was on holidays and try to clear the
> backlog slowly again.
>
> Johann Kerdal wrote:
>
> > Hi guys,
> >
> > I need to unmarshall an XML document to a
> > linkedHashMap<String,ColumnAttributes>
> >
> > The XML document I get from the server system is containing the list of
> > objects:
> > <ColumnAttributes key="BSI_REFIN_INTR_BU_CURRY_AMT">
> >       <name>BSI_REFIN_INTR_BU_CURRY_AMT</name>
> >       <label>Refinancing interest amount in BU currency</label>
> >       <length>8.0</length>
> >       <format>NLNUM18.</format>
> >       <inFormat>NLNUM18.</inFormat>
> >   </ColumnAttributes>
> >
> > As you can see, the key is an attribute of the ColumnAttributes Element.
> >
> > I have tested this code:
> > new NamedMapConverter(LinkedHashMap.class,xstream.getMapper(),
> > "column", "key", String.class, *"column"*, ColumnAttributes.class, true,
> > false, xstream.getConverterLookup())
> >
> > but it generates one element for the key and one for the value.
> >
> > If I use this one:
> > new NamedMapConverter(LinkedHashMap.class,xstream.getMapper(),
> > "column", "key", String.class, *null*, ColumnAttributes.class, true,
> > false, xstream.getConverterLookup())
> >
> > Here is the complete code:
> > XStream xstream = new XStream(new DomDriver());
> >         // XStream xstream = new XStream(new DomDriver());
> >         xstream.alias("columns",LinkedHashMap.class) ;
> >         xstream.alias("column",ColumnAttributes.class) ;
> >         ConverterLookup lookup = xstream.getConverterLookup() ;
> >         Converter conv =
> > xstream.getConverterLookup().lookupConverterForType(String.class) ;
> >         System.out.println(conv.canConvert(String.class)) ;
> >         xstream.registerConverter(
> >          new NamedMapConverter(LinkedHashMap.class,xstream.getMapper(),
> > "column", "key", String.class, null, ColumnAttributes.class, true, false,
> > xstream.getConverterLookup()
> >         ));
> >         // String xml = xstream.toXML(rulesBook.getColumnsAttributes());
> >         // System.out.println(xml);
> >         String xml="<columns><column
> >
>
> key=\"BSI_REFIN_INTR_BU_CURRY_AMT\"><name>BSI_REFIN_INTR_BU_CURRY_AMT</name><label>Refinancing
> > interest amount in BU
> > currency</label><length>8.0</length></column></columns>" ;
> >         LinkedHashMap<String,ColumnAttributes> test =
> > (LinkedHashMap<String,ColumnAttributes>)xstream.fromXML(xml) ;
> >
>
> [snip]
>
> >
> >
> > Is it possible to have the key as an attribute of the value element in
> the
> > XML using the NamedMapconverter?
>
> No. See, a map has normally following XML representation:
>
>  <map>
>   <entry>
>     <key>K</key>
>     <value>V</value>
>   </entry>
>  </map>
>
> where K and/or V might either be a String or another XML structure. The
> NamedMapConverter allows you to use different names for the inner elements
> entry, key and value.
>
> A special mode is offered to drop the entry element:
>
>  <map>
>   <key>K</key>
>   <value>V</value>
>  </map>
>
> Or you might use attributes for key and/or value *if* K resp. V is a String
> i.e. the converter for those objects returns a single value. However, then
> you have to keep the entry element:
>
>  <map>
>   <entry key="K">
>     <value>V</value>
>   </entry>
>  </map>
>
> or:
>
>  <map>
>   <entry key="K" value="V"/>
>  </map>
>
> Nevertheless, the representation for key and value is always present either
> as XML element or attribute.
>
> Since your value type contains the key, you try to drop the key element of
> the map and use the value as entry element instead with an attribute for
> the
> key property. Obviously your situation does not match the functionality of
> this converter.
>
> > If not, do you have any suggestion for me?
> >
> > Any feedback is welcome..
>
> I would actually just use a custom converter for the LinkedHashMap
> (register
> locally if the LinkedHashMap is an element of a higher level, otherwise all
> LinkedHashMaps will be handled):
>
> ================== %< =======================
>  class AttributesConverter implements Converter {
>    Converter listConverter;
>    AttributesConverter(Mapper mapper) {
>      listConverter = new CollectionConverter(mapper);
>    }
>    boolean canConvert(Class t) {
>      return LinkedHashMap.class.equals(t);
>    }
>    void marshal(Object source, HierarchicalStreamWriter writer,
> MarshallingContext context) {
>      Map map = (Map)source;
>      listConverter.marshal(map.values(), writer, context);
>    }
>    Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext
> context) {
>      Collection<ColumnAttributes> values =
>        listConverter.unmarshal(reader, context);
>      Map<String, ColumnAttributes> map = new LinkedHashMap<>();
>      for(ColumnAttributes attr : values) {
>        map.put(attr.getKey(), attr);
>      }
>      return map;
>    }
>  }
>  xstream.registerConverter(
>    new AttributesConverter(xstream.getMapper()));
>  xstream.useAttributeFor(ColumnAttributes.class, "key");
>  xstream.alias("ColumnAttributes", ColumnAttributes.class);
> ================== %< =======================
>
> Hope this helps,
> Jörg
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>     http://xircles.codehaus.org/manage_email
>
>
>

Reply via email to