The defaultValue property in the defaultValue annotation is that the JAXB implementation (JSR-222) should be replaced with the value of the empty element. It seems that they are an error in the reference and MOXy implementations of this when this element is mapped to a property annotated with @XmlList .
Domain model
Root
Here is a sample class with 3 String and 3 List<String> fields, all annotated using @XmlElement(defaultValue="abc") . List<String> fields are also annotated using @XmlList .
import java.util.List; import javax.xml.bind.annotation.*; @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) public class Root { @XmlElement(defaultValue="abc") String singleMissingElement; @XmlElement(defaultValue="abc") String singleEmptyElement; @XmlElement(defaultValue="abc") String singlePopulatedElement; @XmlElement(defaultValue="abc") @XmlList List<String> listMissingElement; @XmlElement(defaultValue="abc") @XmlList List<String> listEmptyElement; @XmlElement(defaultValue="abc") @XmlList List<String> listPopulatedElement; }
Demo code
Demo
Below is some demo code that cancels some XML code and displays the resulting fields from the object. XML elements are populated based on the name of the fields (i.e., missing means that XML is missing, empty means an empty element, and populated means an element with a value).
import java.io.StringReader; import javax.xml.bind.*; public class Demo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(Root.class); StringReader xml = new StringReader("<root><singleEmptyElement/><singlePopulatedElement>populated</singlePopulatedElement><listEmptyElement/><listPopulatedElement>populated</listPopulatedElement></root>"); Unmarshaller unmarshaller = jc.createUnmarshaller(); Root root = (Root) unmarshaller.unmarshal(xml); System.out.println(root.singleMissingElement); System.out.println(root.singleEmptyElement); System.out.println(root.singlePopulatedElement); System.out.println(root.listMissingElement); System.out.println(root.listEmptyElement); System.out.println(root.listPopulatedElement); } }
Exit
The only value that appears unexpectedly is the fifth, which corresponds to an empty element for the List<String> field. Based on defaultValue , I expected this to be a List containing the lines a , b and c .
null abc populated null [] [populated]
Why is this behavior for defaultValue on @XmlElement ?
XML Schema (schema.xsd)
The defaultValue property in the defaultValue annotation corresponds to the default property in the element declaration in the XML schema. Below is a schema equivalent to what we annotated in our Java model.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="root" type="root"/> <xs:complexType name="root"> <xs:sequence> <xs:element name="singleMissingElement" type="xs:string" default="abc" minOccurs="0"/> <xs:element name="singleEmptyElement" type="xs:string" default="abc" minOccurs="0"/> <xs:element name="singlePopulatedElement" type="xs:string" default="abc" minOccurs="0"/> <xs:element name="listMissingElement" minOccurs="0" default="abc"> <xs:simpleType> <xs:list itemType="xs:string"/> </xs:simpleType> </xs:element> <xs:element name="listEmptyElement" minOccurs="0" default="abc"> <xs:simpleType> <xs:list itemType="xs:string"/> </xs:simpleType> </xs:element> <xs:element name="listPopulatedElement" minOccurs="0" default="abc"> <xs:simpleType> <xs:list itemType="xs:string"/> </xs:simpleType> </xs:element> </xs:sequence> </xs:complexType> </xs:schema>
Demo code
Below is the code that will run the SAX analysis with a schema check, where the ContentHandler dumps some information into System.out .
import java.io.*; import javax.xml.XMLConstants; import javax.xml.parsers.*; import javax.xml.validation.*; import org.xml.sax.*; import org.xml.sax.helpers.DefaultHandler; public class ParseDemo { public static void main(String[] args) throws Exception { SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); Schema schema = sf.newSchema(new File("src/forum27528698/schema.xsd")); SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setSchema(schema); SAXParser sp = spf.newSAXParser(); XMLReader xr = sp.getXMLReader(); xr.setContentHandler(new MyHandler()); StringReader xml = new StringReader("<root><singleEmptyElement/><singlePopulatedElement>populated</singlePopulatedElement><listEmptyElement/><listPopulatedElement>populated</listPopulatedElement></root>"); InputSource input = new InputSource(xml); xr.parse(input); } private static class MyHandler extends DefaultHandler { @Override public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException { System.out.print("<" + qName + ">"); } @Override public void characters(char[] ch, int start, int length) throws SAXException { System.out.print(new String(ch, start, length)); } @Override public void endElement(String uri, String localName, String qName) throws SAXException { System.out.println("</" + qName + ">"); } } }
Exit
In the output, we see that the default value was applied to empty elements, but not to missing ones.
<root> <singleEmptyElement>ab c</singleEmptyElement> <singlePopulatedElement>populated</singlePopulatedElement> <listEmptyElement>ab c</listEmptyElement> <listPopulatedElement>populated</listPopulatedElement> </root>