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

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

我可以通过复制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类实现它。

Childclass:

 @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   

对于activatedtrue对象,只有child元素被跳过。

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