使用SimpleXml在序列化之前筛选列表

时间:2013-06-10 09:52:43

标签: java xml-serialization simple-framework

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

我可以通过复制parent对象并在过程中过滤child来做到这一点(我最后可能会这样做)但我想知道是否可以自定义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
        }
    }

}

1 个答案:

答案 0 :(得分:2)

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

但这是一个如何做到这一点的例子:

关键功能是实现Converter,您可以在其中自定义对象的序列化/反序列化方式。在下面的代码中,我为Converter类实现了Child,但是也可以为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中获得<child />

如何使用:

// 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>

childactivated的对象只有true个元素,false被忽略。

注意: 如果您要删除class="java.util.ArrayList",请参阅此处:Remove class= attribute