Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JAXB return null instead empty string

Tags:

java

jaxb

How I can retrieve null value, when unmarshalling, if inside XML attribute value is empty ? Now I make inside my getters checking for null :

public String getLabel() {
    if (label.isEmpty()) {
        return null;
    }
    else {
        return label;
    }
}

But may be exist some other, more elegant way?

Thanks.

like image 719
WelcomeTo Avatar asked Jun 03 '12 11:06

WelcomeTo


People also ask

Is it possible to return an empty string from JQ?

What you probably want, then, is for it to return empty, which, shell-wise, would be represented as an empty string. The problem with returning empty is that it's not a value at all. Right now, if JQ returns null, which you can turn into empty. However, the reverse operation can't be done, because empty is just... well, it isn't.

Is null a valid string value in JQ?

At the end, null could be a valid string value and empty string is just safer based on my over one year use of jq. Sorry, something went wrong. program. Sorry, something went wrong. IMHO, this should be the default for raw-output mode.

How to turn JQ into empty?

Right now, if JQ returns null, which you can turn into empty. However, the reverse operation can't be done, because empty is just... well, it isn't. So, you have two work-arounds for this: Run your script with jq -e, which makes false and null report special exit statuses which you can detect on your shell script.

How does it work in JAXB?

It simply sets one collection to null, the second to an empty list, and the third to a populated list. JAXB models do not require any annotations (see JAXB - No Annotations Required ).


2 Answers

I think your XML looks more or less like this:

    <myElement></myElement>

This, unfortunately, means, that you are passing an empty string.

If you want to pass null you have two options:

  1. Do not pass this tag at all (your XML should not contain <myElement/> tag at all).
  2. Use xsi:nil.

If using xsi:nil, first you have to declare your xml element (in XSD file) as nilable, like this:

    <xsd:element name="myElement" nillable="true"/>

Then, to pass the null value inside XML do this:

    <myElement xsi:nil="true"/>

or this:

    <myElement xsi:nil="true"></myElement>

This way, JAXB knows, that you are passing null instead of an empty String.

like image 182
npe Avatar answered Sep 21 '22 08:09

npe


The answer given by npe is a good one, and specifying how you want null represented would be my recommendation as well. To have xsi:nil marshalled you will want to annotate your property as (see Binding to JSON & XML - Handling Null):

@XmlElement(nillable=true)
public String getLabel() {
    return label;
}

If you don't want to change your XML representation then you could use an XmlAdapter:

EmptyStringAdapter

package forum10869748;

import javax.xml.bind.annotation.adapters.XmlAdapter;

public class EmptyStringAdapter extends XmlAdapter<String, String> {

    @Override
    public String unmarshal(String v) throws Exception {
        if("".equals(v)) {
            return null;
        }
        return v;
    }

    @Override
    public String marshal(String v) throws Exception {
        return v;
    }

}

Foo

You reference an XmlAdapter through the use of the @XmlJavaTypeAdapter annotation. If you would like this XmlAdapter applied to all Strings then you could register it at the package level (see JAXB and Package Level XmlAdapters).

package forum10869748;

import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlRootElement
public class Foo {

    private String label;

    @XmlJavaTypeAdapter(EmptyStringAdapter.class)
    public String getLabel() {
        return label;
    }

    public void setLabel(String label) {
        this.label = label;
    }

}

Demo

package forum10869748;

import java.io.File;
import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Foo.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum10869748/input.xml");
        Foo foo = (Foo) unmarshaller.unmarshal(xml);

        System.out.println(foo.getLabel());
    }

}

input.xml

<?xml version="1.0" encoding="UTF-8"?>
<foo>
    <label></label>
</foo>

Output

null
like image 29
bdoughan Avatar answered Sep 19 '22 08:09

bdoughan