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 > > >