Prevent from including empty tag in empty ElementList in ElementListUnion

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 is the only way to make the structure work for elements containing both children and text. This works great when text is present and the element contains elements as well and creates the following xml:

<parent>
    <values>val 1</values>
    <values>val 2</values>
    some text
</parent>

      

However, sometimes the list of items contains no items and only text (this means that the ValueUnion List contains only one item, a line of text). This, however, results in the following XML:

<parent>
    <values />
    some text
</parent>

      

And here's the problem, as it causes the server to suffocate the empty tag <values />

. Unfortunately, I have no control over the code on the server, and am looking for a way to make Simple ignore an empty tag if the list element contains no elements.

+3


source to share


1 answer


I have a workaround for you. It's ugly, but the concept might help you. Instead of element annotations, you can use a custom Converter

one that serializes your objects.

  • Example

    Class:

(Contains list, text, and other items 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
}

      

In fact, you only need annotations @Convert(ExampleConverter.class)

, and @Root

here, as serialization is done at 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 text will be set even if there are other items. However, this decision may disrupt your formation; the text and the end tag will be on the same line. You can fix this problem by inserting a new line.

  • Using:

Create a serializer and your strategy and write / read



Serializer ser = new Persister(new AnnotationStrategy()); // 'AnnotationStrategy is important here!
ser.write(...); // write / read

      

  • <strong> Examples:

With items 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 items 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>

      

Pay attention to the "problem" described above!

+2


source







All Articles