1
votes

I have one particular element in an XSD schema that I'd like JAXB to treat empty element content as null rather than the empty string. The model classes are generated by XJC.

I've seen this answer for marshalling empty string to null globally, and I'm stuck with the RI of JAXB so I'm guessing this won't work for me.

Is there another approach I can take, given that I only need it for one particular element?

1

1 Answers

1
votes

Since this is just for one element, below is one way you could get this to work with any JAXB implementation.

Java Model

Foo

Setup your class to use field access by leveraging the @XmlAccessorType annotation. Then initialize the field corresponding to the element as "". The implement the get/set methods to treat "" as null.

import javax.xml.bind.annotation.*;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Foo {

    private String bar = "";

    public String getBar() {
        if(bar.length() == 0) {
            return null;
        } else {
            return bar;
        }
    }

    public void setBar(String bar) {
        if(null == bar) {
            this.bar = "";
        } else {
            this.bar = bar;
        }
    }

}

Demo Code

Below is some demo code you can run to see that everything works.

input.xml

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

Demo

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/forum18611294/input.xml");
        Foo foo = (Foo) unmarshaller.unmarshal(xml);

        System.out.println(foo.getBar());

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(foo, System.out);
    }

}

Output

null
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<foo>
    <bar></bar>
</foo>