Unmarshall XML object List into HashMap with XMLAdapter



I've got the following XML



<demographics>
<field>
<value>03290</value>
<XMLtag>study_identifier</XMLtag>
</field>
<field>
<value>somename</value>
<XMLtag>name</XMLtag>
</field>
<filename>bbRad_BUILD_dem_03290_BUILD_006742.xml</filename>
<study_cache_dir>somestring</study_cache_dir>
</demographics>


The annotations in Demographics2 class are currently like this:



@XmlRootElement( name = "demographics" )
public class Demographics2
{
@XmlElement( name = "study_cache_dir" )
private String studyCacheDir;

@XmlElement( name = "filename" )
private String filename;

@XmlElement( name = "field" )
private List<Field2> mutivalueFields;
}


Field2.java ( simple container ):



public class Field2
{
@XmlElement( name = "XMLtag")
private String xmlTag;
@XmlElement( name = "value" )
private String value;
}


If I unmarshall the XML it works fine, and multivalueFields contains a list of two Field2 objects. What I want is to convert the List< Field2 > to be HashMap< String, Field2 > where the String key will be the xmlTag value from the Field2 object.


So far I've tired changing Demographics2 class and using a XmlAdapter as follows:



@XmlElement( name = "field" )
@XmlJavaTypeAdapter( MultiValueFieldsAdapter.class )
private Map< String, Field2> mutivalueFields;


I thought the adapter should work like this:



public class MultiValueFieldsAdapter extends XmlAdapter< List<Field2>, Map<String, Field2>> {

@Override
public List<Field2> marshal( Map<String, Field2> arg0) throws Exception {

// loop all in Map and just add the Field2 objects to a list then
// return the list
return null;
}

@Override
public Map<String, Field2> unmarshal( List<Field2> arg0 ) throws Exception {

// The problem is here arg0 will be emtpy list, unless we make arg0 a Field2 object
// it seems to be calling unmarshal for each Field2 object, rather than some list

// loop each Field2 and add to Map
Map<String, Field2> newMap = new HashMap<String, Field2>( arg.length() );

for ( Field2 f : arg0 )
newMap.put( f.xmlTag, f );
}
}


My MultiValueFieldsAdapter is wrong, but I also think maybe I have my annotations are incorrect? I can't figure out how it manages to put all the Field2 objects into a List with just @XmlElement( name = "field" ), it must be JAXB that's doing that conversion, but I can't find how to override it and put into map.


Unfortunately the XML is fixed and I have to work with that format of XML. What I'm trying to avoid is that once the XML has been unmarshalled I don't want to have to loop through the multivalueFields and checking each xmlTag of each Field2 for my match. If they are in a Map I can do:



Field2 nameField = multivalueFields.get( "name" );

No comments:

Post a Comment