Gregory Orlov
Gregory Orlov

Reputation: 537

How to create Class and object from xml on the flight?

I have a XML file with the following structure:

<object type="People">
    <field id="name" type="class java.lang.String" value="Ivan"/>
    <field id="age" type="class java.lang.Integer" value="23"/>
    <field id="salary" type="class java.lang.Double" value="50.0"/>
</object>

But the object type, and fields can be differ.

For example:

<object type="Worker">
    <field id="lastName" type="class java.lang.String" value="Ivan"/>
    <field id="height" type="double" value="170.00"/>
    <field id="salary" type="double" value="50.0"/>
</object>

Is it possible to create object from XML with unknown field?

Upvotes: 1

Views: 1307

Answers (1)

Compass
Compass

Reputation: 5937

When life gives you flexible objects, a wrapper is your friend.

Your "XmlObject" would ideally look like this.

public class XmlObject {
    final String type; 
    Map<String, ObjectWrapper> map = new Map<>();

    public XmlObject(String type) {
        this.type = type;
    }

    public void put(String key, ObjectWrapper object) {
        map.add(key, object);
    }

    public ObjectWrapper get(String key) {
        return map.get(key);
    }
}

Your wrapper then uses Generics, with the option to return the Class type.

public class ObjectWrapper<T> {

    private T value;

    public ObjectWrapper (T value) {
        this.value = value;
    }

    //from http://stackoverflow.com/a/8019188/2958086
    public Class<T> getPersistentClass() {
        if (persistentClass == null) {
            this.persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        }
        return persistentClass;
    }
}

You provide the Object type when declaring, as well as any sort of type parsing or data conversion, if necessary. I assume the types are standard parsable types, so you can in your XML parser go process and store based on type.

String key, type, value; //from xml;
ObjectWrapper object;
if(type.contains("String")) {
    object = new ObjectWrapper<String>(value);
}
else if(type.contains("Double")) {
    object = new ObjectWrapper<Double>(Double.parseDouble(value));
}

xmlObject.add(key, object);

After that, you can get the object based on the key, or get a keymap using standard map functions. To get an object's type, you can get its persistent class.

Upvotes: 1

Related Questions