【问题标题】:Filter a list before serialization using SimpleXml使用 SimpleXml 在序列化之前过滤列表
【发布时间】:2013-06-10 09:52:42
【问题描述】:

我正在尝试序列化包含childs 列表的parent。这些childs 有一个activated 布尔字段,我希望生成的XML 只包含childs,其中activated 属性设置为true

我可以通过复制parent 对象并在此过程中过滤childs 来做到这一点(我可能会在最后这样做)但我想知道是否可以自定义 SimpleXML 以获得相同的结果.

编辑

我使用了 ollo 给出的响应。我刚刚更改了Converter 实现以使用子类的原始注释。

新的Converter 实现:

public class ChildConverter implements Converter<Child>
{
    @Override
    public Child read(InputNode node) throws Exception
    {
        throw new UnsupportedOperationException("Not supported yet.");
    }


    @Override
    public void write(OutputNode node, Child value) throws Exception
    {
        if( value.isActived() == true ) // Check if 'activated' flag is set
        {
            // Set valus of the child
            //We don't use an annotation strategy for this persister to avoid
            //a recursive call to this method.
            Serializer serializer = new Persister();
            serializer.write(value, node);
        }
        else
        {
            node.remove(); // Remove the node since we don't need it
        }
    }

}

【问题讨论】:

    标签: java xml-serialization simple-framework


    【解决方案1】:

    更多信息(代码、预期的 XML 等)会有所帮助...

    但这里有一个示例:

    关键特性是实现Converter,您可以在其中自定义对象的序列化/反序列化方式。在下面的代码中,我为Child 类实现了一个Converter,但是也可以为Parent 类实现它。

    Child 类:

    @Root(name = "child")
    @Convert(value = ChildConverter.class) // Set the Converter
    public class Child
    {
        private boolean actived;
        @Element(name = "value", required = true)
        private String value;
        @Element(name = "value2", required = true)
        private int secondValue;
    
    
        public Child(boolean actived, String value, int secondValue)
        {
            this.actived = actived;
            this.value = value;
            this.secondValue = secondValue;
        }
    
    
    
        public boolean isActived()
        {
            return actived;
        }
    
        public String getValue()
        {
            return value;
        }
    
        public int getSecondValue()
        {
            return secondValue;
        }
    
        // ...
    }
    

    除了activated 标志之外,这个类还有另外两个成员来展示如何序列化它们。

    Parent 类:

    @Root(name = "parent")
    public class Parent
    {
        @ElementList(name = "childs", required = true)
        private List<Child> childs;
    
    
        public Parent()
        {
            this.childs = new ArrayList<>();
        }
    
    
    
        public void addChild(Child child)
        {
            childs.add(child);
        }
    
        // ...
    }
    

    Converter 实现:

    public class ChildConverter implements Converter<Child>
    {
        @Override
        public Child read(InputNode node) throws Exception
        {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    
    
        @Override
        public void write(OutputNode node, Child value) throws Exception
        {
            if( value.isActived() == true ) // Check if 'activated' flag is set
            {
                // Set valus of the child
                node.setValue(value.getValue());
                node.setAttribute("secondValue", String.valueOf(value.getSecondValue()));
            }
            else
            {
                node.remove(); // Remove the node since we don't need it
            }
        }
    
    }
    

    到目前为止,实现并不是很复杂。首先我们检查是否设置了activated。如果是,我们将对象值填充到节点中,如果未设置,我们将删除节点(否则您将在 XML 中获得 &lt;child /&gt;)。

    使用方法:

    // Some test data
    Parent p = new Parent();
    p.addChild(new Child(true, "a", 1));
    p.addChild(new Child(true, "b", 2));
    p.addChild(new Child(false, "c", 3)); // "disabled"
    p.addChild(new Child(true, "d", 4));
    p.addChild(new Child(false, "e", 5)); // "disabled"
    p.addChild(new Child(false, "f", 6)); // "disabled"
    
    
    final File f = new File("test.xml");
    
    Serializer ser = new Persister(new AnnotationStrategy()); // Don't forget 'AnnotationStrategy'!
    ser.write(p, f); // Serialize to a file or whatever you need
    

    最后...

    XML 输出:

    <parent>
       <childs class="java.util.ArrayList">
          <child secondValue="1">a</child>
          <child secondValue="2">b</child>
          <child secondValue="4">d</child>
       </childs>
    </parent>
    

    activatedtrue 的对象只有 child 元素,false 的元素将被跳过。

    注意:如果你想删除class="java.util.ArrayList",请看这里:Remove class= attribute

    【讨论】:

    • 感谢您的回复,对于我的问题中缺少代码示例感到抱歉。但看来你还是抓住了这个问题:)。我会在几个小时内测试这个解决方案,但我认为这是正确的答案。
    • 有任何问题欢迎留言;-)
    • 好吧,它就像一个魅力,但我还有一个问题:在 write 方法中,我有没有办法使用放置在它上的注释将 Child 实例序列化到节点?因为,如果我理解正确的话,在 Child 类的 value 和 secondValue 字段上的两个 Element 注解是注意使用的。
    • 好的,找到了。如果您有兴趣,请在问题中查看我的版本。
    猜你喜欢
    • 1970-01-01
    • 2019-05-19
    • 1970-01-01
    • 1970-01-01
    • 2011-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多