问题
I have the following code in one of my classes:
@Text(required=false)
@ElementListUnion({
@ElementList(required = false, inline = true, type = com.company.Child.class, entry="values")
})
public List<Object> valueUnion;
Note that this seems to be the only way to get the framework to work with elements that contain both children and text. This works great when text is present and the elementlist contains elements as well, and produces the following xml:
<parent>
<values>val 1</values>
<values>val 2</values>
some text
</parent>
However, sometimes the element list contains no elements, with only the text being present (meaning the valueUnion List only contains one element, the string of text). This however, results in the following XML:
<parent>
<values />
some text
</parent>
And herein lies the problem, as this causes the server to choke over the empty <values />
tag. Unfortunately I do not have control over the code on the server, and I am looking for a way to force Simple to ignore the empty tag if the elementlist contains no elements.
回答1:
I have a workaround for you. Its not beautiful, but the concept can help you here.
Instead of element-annotations you can use a custom Converter
which serializes your Objects.
Example
Class:
(Contains the list, the text and other elements you need)
@Root(name="parent")
@Convert(ExampleConverter.class)
public class Example
{
private String text; // Save the text you want to set ('some text' in your code)
private List<Object> valueUnion;
// Constructor + getter / setter
}
Actually you only need the @Convert(ExampleConverter.class)
and @Root
Annotations here, since the serialization is done in your own converter (ExampleConverter
).
ExampleConverter
Class:
(Serialize / Deserialize your Object here)
public class ExampleConverter implements Converter
{
@Override
public Object read(InputNode node) throws Exception
{
/* TODO: Deserialize your class here (if required). */
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void write(OutputNode node, Object value) throws Exception
{
final Example val = (Example) value;
final List<Object> l = val.getValueUnion();
if( !l.isEmpty() ) // if there are elements, insert their nodes
{
for( Object obj : l )
{
node.getChild("values").setValue(obj.toString());
}
}
else
{
node.getChild("values").setValue(""); // this creates <values></values> if list is empty
}
node.setValue(val.getText()); // Set the text (1)
}
}
(1): This will set your text even if there are some other elements. However this solution may break your formating; the text and the closing tag will be on the same line. You can solve this by inserting a new line.
- Usage:
Create a serializer, et your strategy and write / read
Serializer ser = new Persister(new AnnotationStrategy()); // 'AnnotationStrategy is important here!
ser.write(...); // write / read
- Examples:
With elements in the list:
Example t = new Example();
t.setText("abc"); // Set the text
t.getValueUnion().add("value1"); // Add some elements to list
t.getValueUnion().add("value2");
Serializer ser = new Persister(new AnnotationStrategy());
ser.write(t, f); // 'f' is the file to write
Output:
<parent>
<values>value1</values>
<values>value2</values>abc</parent>
Without elements in the list:
Example t = new Example();
t.setText("abc"); // Set the text
Serializer ser = new Persister(new AnnotationStrategy());
ser.write(t, f); // 'f' is the file to write
Output:
<parent>
<values></values>abc</parent>
Please notice the formating "problem" as said before!
来源:https://stackoverflow.com/questions/14443749/prevent-inclusion-of-empty-tag-for-an-empty-elementlist-in-an-elementlistunion