【问题标题】:Simple-XML: Overriding an element name at runtimeSimple-XML:在运行时覆盖元素名称
【发布时间】:2012-10-04 09:43:51
【问题描述】:

我正在使用 simple-xml 在我的 Java 应用程序中执行 XML 序列化/反序列化。我有一堂课如下:

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

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

    //...
    //...
}

现在,这将生成如下所示的 XML:

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

问题:

如何在运行时覆盖元素名称,以便在某些情况下,XML 读取如下?

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

编辑:

为了澄清,我只想在某些情况下覆盖元素名称。所以基本上,

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

【问题讨论】:

  • 为什么 @Element(name="updt_int")@Element(name="ts") 不符合您的需求?
  • 有趣。我想到的最明显的方法是将 ElementUnion 与您自己的自定义类型一起使用,以便元素名称根据存储变量的类型而变化。但这似乎有点 hacky...
  • @Florent 就像我在 Q 中提到的那样,我只希望在 某些 情况下使用这种覆盖。长答案:我将它用于 RESTful Web 服务,并且根据请求的 URL,我希望对同一资源有两个单独的表示。
  • @MattGibson 是的——我也是这么想的。但问题是,它们确实是同一类型,只是表示形式不同。我想这可以使用ConverterVisitorStrategy 来实现——我只是不知道具体是如何实现的。
  • 是的,看起来访客是最好的选择。这是我能找到的最接近半体面的例子:old.nabble.com/… 但遗憾的是我今天在(非基于 Java 的)工作,所以我不能摆弄和尝试一些东西......

标签: java xml simple-framework


【解决方案1】:

感谢this comment,我找到了一种在这种情况下实现序列化的简单方法。

但是,我无法反序列化这样的 XML 文档。这是我的部分解决方案:

/*
 * 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());
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-23
    • 1970-01-01
    • 2013-01-10
    • 1970-01-01
    • 1970-01-01
    • 2020-04-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多