Search code examples
javaxmlxstream

How to convert different child XML elements from an XML node into a generic java type instances using XStream?


From my simple XML below, I want to create an instance of SomeApplication with a collection of Field instances where each Field instance to represent a child element of <some-application>. The Field instances would have two String properties, name and value which are assigned from the node name and node value respectively.

XML input:

<some-application>
    <field1>foo</field1>
    <field2>bar</field2>
</some-application>

Java types:

public class Field {

    private String name;   
    private String value;

    public Field(String name, String value) {
        this.name = name;
        this.value = value;
    }

    public String getName(){
        return name;
    }

    public String getValue(){
        return value;
    }
}

public class SomeApplication {

    private List<Field> fields;

    public SomeApplication(){
        fields = new ArrayList<Field>();
    }

    public void addField(Field field){
        fields.add(field);
    }
}

What would be the best strategy for converting field elements (children of <some-application>) to Field instances?

Please note that I've simplified the requirement for the sake of brevity.

Thanks in advance.


Solution

  • I've managed to achieve it using a custom converter - SomeApplicationConverter. In my custom converter, while unmarshalling, for every child node I encounter, I create my Field type instance using the node name and value. Below is my custom converter

    public class SomeApplicationConverter implements Converter {
    
        @Override
        @SuppressWarnings("unchecked")
        public boolean canConvert(Class type) {
            if (type.equals(SomeApplication.class)) {
                return true;
            }
            return false;
        }
    
        @Override
        public void marshal(Object source, HierarchicalStreamWriter writer,
                MarshallingContext context) {
            throw new UnsupportedOperationException(
                    "Marshalling is not supported yet");
        }
    
        @Override
        public Object unmarshal(HierarchicalStreamReader reader,
                UnmarshallingContext context) {
            SomeApplication application = new SomeApplication();
            while (reader.hasMoreChildren()) {
                reader.moveDown();
                String name = reader.getNodeName();
                String value = reader.getValue();
                Field field = new Field(name, value);
                application.addField(field);
                reader.moveUp();
            }
            return application;
        }