I am trying to serialize a parent
which contains a list of child
s. These child
s have an activated
boolean field, and I want that the resulting XML contains only the child
s wich an activated
attribute set to true
I could do this by copying the parent
object and filtering the child
s in the process (and I may do this at the end) but I am wondering if it is possible to customize SimpleXML to have the same result.
EDIT
I used the response given by ollo. I just changed the Converter
implementation for using the original annotations of the child classes.
The new Converter
implementation:
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
}
}
}
Some more informations (code, expected XML etc.) would be helpful ...
But here's an example how you can do this:
The key feature is implementing a Converter
, where you can customize how objects are serialized / deserialized. In the following code I implement a Converter
for the Child
class, however it's possible to implement it for the Parent
class instead too.
The 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;
}
// ...
}
Beside the activated
flag this class has two other members to show how do serialize them.
The Parent
class:
@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);
}
// ...
}
The Converter
implementation:
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
}
}
}
The implementation is not very complex so far. First we check if activated
is set. If yes we fill the objects value into the node, if it's not set we remove the node (else you'll get a <child />
in your XML).
How to use:
// 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
And finally ...
The XML output:
<parent>
<childs class="java.util.ArrayList">
<child secondValue="1">a</child>
<child secondValue="2">b</child>
<child secondValue="4">d</child>
</childs>
</parent>
There are only child
elements for object where activated
was true
, those with false
are skipped.
Note: If you want to remove class="java.util.ArrayList"
please see here: Remove class= attribute
来源:https://stackoverflow.com/questions/17021119/filter-a-list-before-serialization-using-simplexml