curioustechizen
curioustechizen

Reputation: 10672

Simple-XML: Overriding an element name at runtime

I am using simple-xml to perform XML serialization/deserialization in my Java application. I have a class as follows:

@Root(name="config")
public class Config{
    @Element(name="update_interval")
    private int updateInterval;

    @Element(name="timestamp")
    private long timestamp;

    //...
    //...
}

Now, this would produce XML like the following:

<config>
    <update_interval>2000</update_interval>
    <timestamp>1234567890</timestamp>
</config>

Question:

How can I override the element name at runtime, so that in some cases, the XML reads as follows?

<config>
    <updt_int>2000</updt_int>
    <ts>1234567890</ts>
</config>

Edit:

To clarify, I want to override the element names only in some cases. So basically,

if(condition){
    //Override Element Names
} else {
    //Serialize Normally
}

Upvotes: 1

Views: 1352

Answers (1)

curioustechizen
curioustechizen

Reputation: 10672

I found an easy way to achieve serialization in this case, thanks to this comment.

However, I haven't been able to de-serialize such an XML document. Here's my partial solution:

/*
 * Config.java
 */

@Root(name="config", strict = false)
public class Config {

    @Element(name="timestamp", required = false)
    private long timestamp;

    @Element(name = "update_interval", required = false)
    private int updateInterval;

    public Config() {
    }

    public int getUpdateInterval() {
        return updateInterval;
    }

    public void setUpdateInterval(int updateInterval) {
        this.updateInterval = updateInterval;
    }

    public long getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(long timestamp) {
        this.timestamp = timestamp;
    }

    @Override
    public String toString() {
        return "Config{" +
                "timestamp=" + timestamp +
                ", updateInterval=" + updateInterval +
                '}';
    }
}



/*
 * Custom Visitor implementation
 */
public class MyInterceptor implements Visitor {

    private static int sReadCount = 0;
    private static int sWriteCount = 0;
    @Override
    public void read(Type field, NodeMap<InputNode> node) throws Exception {
        /*
         * This is where I need help!
         *
         * 
         * This method is only called once: for the <config> node
         * It is not called for the other nodes since they are not "recognized" 
         * i.e., there are no annotations for the nodes <ts> and <updt_int>
         */

        System.out.println("Read Count : "+ (++sReadCount));
        System.out.println(node.getName());
        System.out.println(node.getNode());

    }

    @Override
    public void write(Type field, NodeMap<OutputNode> node) throws Exception {

        /* 
         * This works like a charm.
         */
        System.out.println("Write Count : "+ (++sWriteCount));
        OutputNode opNode = node.getNode();
        if("timestamp".equals(opNode.getName())){
            opNode.setName("ts");
        }
        if("update_interval".equals(opNode.getName())){
            opNode.setName("updt_int");
        }

    }

}

/*
 *
 */ Main class
public class Bootstrap {

    static final Random RANDOM = new Random();
    public static void main(String [] args){
        Config cfg = new Config();
        cfg.setTimestamp(RANDOM.nextLong());
        cfg.setUpdateInterval(1000);

        Serializer serializer = new Persister(new VisitorStrategy(new MyInterceptor()));

        StringWriter writer = new StringWriter();
        try {
            serializer.write(cfg, writer);
        } catch (Exception e) {
            e.printStackTrace();
        }

        String serialized = writer.toString();
        System.out.println(serialized);

        Config desCfg = null;
        try {
            desCfg = serializer.read(Config.class, serialized);
        } catch (Exception e) {
            e.printStackTrace();
        }

        if(desCfg != null){
            System.out.println(desCfg.toString());
        }
    }
}

Upvotes: 1

Related Questions