Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Attribute "empty" not working as expected with SimpleFramework

So I was trying to set an empty attribute when an element has no value.

So my class looks like this:

@Order(attributes = { "name" })
public class TypeNumber {
    @Attribute(required = false)
    protected String name;

    @Element(required = false)
    @Attribute(empty = "xsi:nil=\"true\"")
    protected BigDecimal value;

    //getter setter methods goes here  
}

In case of empty value I was expecting output:

<field name="some_name">
    <value xsi:nil="true"/>
 </field>

While the actual output is:

<field name="some_name"/>

Any idea why the empty attribute is not working as expected? Or am I doing it wrong ?

Note: I am using SimpleFramework XML with VisitorStrategy. So, can't use AnnotationStrategy. Also I have custom Visitor to read and write nodes.

like image 717
TheLittleNaruto Avatar asked Jan 02 '17 11:01

TheLittleNaruto


Video Answer


1 Answers

You will need a custom Converter...

Right now your outputs are:
<typeNumber name="original" value="10"/>
and
<typeNumber name="original_empty" value="xsi:nil=&quot;true&quot;"/>

So let's get started!

First thing you got to do is pass AnnotationStrategy to the constructor of your Persister:

Serializer serializer = new Persister(new AnnotationStrategy());

.. then create a custom Converter in your model:

@Root(name = "TypeNumberFixed")
@Order(attributes = {"name"})
@Convert(TypeNumberFixed.FixConverter.class)
class TypeNumberFixed {
    @Attribute(required = false)
    protected String name;

    @Element(required = false, name = "value")
    protected BigDecimal value;


    public static class FixConverter implements Converter<TypeNumberFixed> {

        @Override
        public TypeNumberFixed read(InputNode inputNode) throws Exception {
            //Implement your own deConverter
            return null;
        }

        @Override
        public void write(OutputNode node, TypeNumberFixed value) throws Exception {
            node.setAttribute("name",value.name);
            OutputNode valueNode = node.getChild("value");
            if (value.value != null) {
                valueNode.setValue(value.value.toPlainString());
            } else {
                valueNode.setAttribute("xsi:nil", "true");
            }
        }
    }
}

This will generate following output for empty/nonempty values respectively:

typeNumberFixed.value = null:

<TypeNumberFixed name="new_empty">
   <value xsi:nil="true"/>
</TypeNumberFixed>

typeNumberFixed.value = 30:

<TypeNumberFixed name="new">
   <value>30</value>
</TypeNumberFixed>

Here's the repo if you're interested.

like image 145
nana Avatar answered Oct 23 '22 09:10

nana