Note. I am an EclipseLink JAXB (MOXy) and a member of the JAXB Group (JSR-222) .
The following example requires the use of MOXy as a JAXB provider. This is because JAXB RI does not invoke the XmlAdapter when the field / property is null. For information on specifying MOXy as a JAXB provider, see:
StringAdapter
XmlAdapter converts a String value into an object with a property annotated with @XmlValue .
package forum8986842; import javax.xml.bind.annotation.*; import javax.xml.bind.annotation.adapters.XmlAdapter; public class StringAdapter extends XmlAdapter<StringAdapter.AdaptedString, String>{ @Override public String unmarshal(AdaptedString adaptedString) throws Exception { if(null == adaptedString) { return null; } String string = adaptedString.value; if("".equals(string)) { return null; } return string; } @Override public AdaptedString marshal(String string) throws Exception { AdaptedString adaptedString = new AdaptedString(); adaptedString.value = string; return adaptedString; } public static class AdaptedString { @XmlValue public String value; } }
Root
The @XmlJavaTypeAdapter annotation @XmlJavaTypeAdapter used to specify the XmlAdapter :
package forum8986842; import javax.xml.bind.annotation.*; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; @XmlRootElement(name="Root") public class Root { private String item; @XmlElement(name = "Item", required = true, nillable = true) @XmlJavaTypeAdapter(StringAdapter.class) public String getItem() { return item; } public void setItem(String item) { this.item = item; } }
Demo
The following code can be used to demonstrate the above mapping. Two documents are used, one with an empty Item , and the other with a filled Item .
package forum8986842; import java.io.StringReader; import javax.xml.bind.*; public class Demo { private JAXBContext jc; public Demo() throws JAXBException { jc = JAXBContext.newInstance(Root.class); } public static void main(String[] args) throws Exception { Demo demo = new Demo(); demo.demo("<Root><Item/></Root>"); demo.demo("<Root><Item>Hello World</Item></Root>"); } private void demo(String xml) throws JAXBException { System.out.println("\n\nINPUT: " + xml); StringReader stringReader = new StringReader(xml); Unmarshaller unmarshaller = jc.createUnmarshaller(); Root root = (Root) unmarshaller.unmarshal(stringReader); System.out.println("ITEM: " + root.getItem()); System.out.print("OUTPUT: "); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true); marshaller.marshal(root, System.out); } }
Exit
The following is the result of running the demo code:
INPUT: <Root><Item/></Root> ITEM: null OUTPUT: <Root><Item/></Root> INPUT: <Root><Item>Hello World</Item></Root> ITEM: Hello World OUTPUT: <Root><Item>Hello World</Item></Root>
Additional Information
source share