Reputation: 10672
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>
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
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