Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to serialize a null string as a single empty tag?

I serialize this class using the Simple XML framework:

@Root
public class HowToRenderEmptyTag {
    @Element(required=false)
    private String nullString;
}

I want to get:

<howToRenderNull>
    <nullString/>
</howToRenderNull>

But I get:

<howToRenderNull/>

I have tried assigning an empty string:

@Root
public class HowToRenderEmptyTag {
    @Element(required=false)
    private String emptyString = "";
}

But then I get one opening and one closing tag:

<howToRenderNull>
    <emptyString></emptyString>
</howToRenderNull>

This is not sadly accepted correctly by the client consuming the XML and changing the client is out of scope.

Any ideas on how to get the single empty tag?

like image 808
Michael Avatar asked Jun 20 '13 12:06

Michael


People also ask

Is a null string an empty string?

The Java programming language distinguishes between null and empty strings. An empty string is a string instance of zero length, whereas a null string has no value at all. An empty string is represented as "" . It is a character sequence of zero characters.

Does isEmpty work on null?

isEmpty(< string >)​Returns true if the string is null or empty.

How do you serialize a null object in Java?

By default, the Gson object does not serialize the fields with null values to JSON. If a field in a Java object is null, Gson excludes it. We can force Gson to serialize null values via the GsonBuilder class. We need to call the serializeNulls() method on the GsonBuilder instance before creating the Gson object.

How do you replace a blank null string in Java?

You can use String's replace() method to replace null with empty String in java. str = str. replace(null,""); As String is immutable in java, you need to assign the result either to new String or same String.


2 Answers

You can use a trick here; write a converter for your element which changes the behaviour:

HowToRenderEmptyTag class:

@Root(name = "howToRenderEmptyTag")
public class HowToRenderEmptyTag
{
    @Element(name = "emptyString", required = false)
    @Convert(value = EmptyElementConverter.class) // Set the converter for this element
    private String nullString;


    // ...
}

EmptyElementConverter class:

public class EmptyElementConverter implements Converter<String>
{
    @Override
    public String read(InputNode node) throws Exception
    {
        /* Implement if required */
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void write(OutputNode node, String value) throws Exception
    {
        /* Simple implementation: do nothing here ;-) */
    }
}

You don't have to implement this Converter for strings - in this example it's optional. You can keep the class generic or implement it for Object so you can use it for any king of element.

Example:

final File f = new File("test.xml");

HowToRenderEmptyTag example = new HowToRenderEmptyTag("");

Serializer ser = new Persister(new AnnotationStrategy()); // Don't forget AnnotationStrategy here!
ser.write(example, f);

and finally the result:

<howToRenderEmptyTag>
   <emptyString/>
</howToRenderEmptyTag>

Since you have used both, I'm not sure if the empty element needs the name emptyString or nullString but it's not a big thing to change it :-)

like image 154
ollo Avatar answered Oct 12 '22 13:10

ollo


You no need to create a converter to resolve your problem. All you need to do to get:

<howToRenderNull>
    <EmptyNode/>
</howToRenderNull>

is:

@Root
public class HowToRenderEmptyTag {
    @Element(name = "emptyNode", required=false)
    private EmptyNode emptyNode;

    @Root
    public static class EmptyNode {}
}

the result:

<howToRenderEmptyTag>
    <emptyNode/>
</howToRenderEmptyTag>

Cheers! :)

like image 23
Michał Sobierski Avatar answered Oct 12 '22 14:10

Michał Sobierski