使用SimpleXml在序列化之前筛选列表
我正在尝试序列化包含child
列表的parent
。 这些child
节点有一个activated
布尔字段,我希望生成的XML只包含activated
属性设置为true
的child
节点
我可以通过复制parent
对象并在过程中过滤child
进程来做到这一点(我最后可能会这样做),但我想知道是否可以自定义SimpleXML以获得相同的结果。
编辑
我使用了ollo给出的回答。 我刚刚更改了Converter
实现以使用子类的原始注释。
新的Converter
实现:
public class ChildConverter implements Converter { @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 } } }
一些更多的信息(代码,预期的XML等)会有所帮助……
但这是一个如何做到这一点的例子:
关键function是实现Converter
,您可以在其中自定义对象的序列化/反序列化方式。 在下面的代码中,我为Child
类实现了一个Converter
,但是也可以为Parent
类实现它。
Child
class:
@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 childs; public Parent() { this.childs = new ArrayList<>(); } public void addChild(Child child) { childs.add(child); } // ... }
Converter
实现:
public class ChildConverter implements Converter { @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中获得
)。
如何使用:
// 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输出:
a b d
对于activated
为true
对象,只有child
元素被跳过。
注意:如果要删除class="java.util.ArrayList"
请参见此处: 删除class = attribute