2

我正在尝试序列化parent包含 s 列表的 a child。这些childs 有一个activated布尔字段,我希望生成的 XML 只包含child一个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
        }
    }

}
4

1 回答 1

2

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

但这里有一个例子,你可以如何做到这一点:

关键特性是实现Converter,您可以在其中自定义对象的序列化/反序列化方式。在下面的代码中,我ConverterChild该类实现了一个,但是也可以为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设置。如果是,我们将对象值填充到节点中,如果未设置,我们删除节点(否则您将<child />在 XML 中获得 a)。

如何使用:

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

只有child对象 where activatedwas的元素true,那些 withfalse被跳过。

注意:如果要删除,class="java.util.ArrayList"请参见此处:删除 class= 属性

于 2013-06-13T13:03:22.410 回答