How to represent null value as empty element with JAXB?

前端 未结 4 776
[愿得一人]
[愿得一人] 2020-12-01 06:58

My XSD structure is like the below:-


         


        
4条回答
  •  悲&欢浪女
    2020-12-01 07:35

    NOTE #1: I am the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.


    NOTE #2: The output that you are seeing matches what you have mapped with JAXB. For more information see:

    • http://blog.bdoughan.com/2012/04/binding-to-json-xml-handling-null.html

    REPRESENTING NULL AS AN EMPTY ELEMENT

    If you want to represent null as an empty element, there are a couple of options.

    Option #1 - Using the Standard JAXB APIs

    DateAdapter

    You could use an XmlAdapter to change the way an instance of Date is marshalled to XML. We will convert the date to an instance of a class that has one property mapped with @XmlValue (see http://blog.bdoughan.com/2011/06/jaxb-and-complex-types-with-simple.html). The JAXB RI does not call the XmlAdapter mechanism for null values, so you will need to use a JAXB impl that does such as MOXy.

    package forum11743306;
    
    import javax.xml.bind.annotation.XmlValue;
    import javax.xml.bind.annotation.adapters.XmlAdapter;
    import javax.xml.datatype.XMLGregorianCalendar;
    
    public class DateAdapter extends XmlAdapter{
    
        @Override
        public AdaptedDate marshal(XMLGregorianCalendar date) throws Exception {
            AdaptedDate adaptedDate = new AdaptedDate();
            adaptedDate.value = date;
            return adaptedDate;
        }
    
        @Override
        public XMLGregorianCalendar unmarshal(AdaptedDate adaptedDate) throws Exception {
            return adaptedDate.value;
        }
    
        public static class AdaptedDate {
            @XmlValue
            public XMLGregorianCalendar value;
        }
    
    }
    

    Root

    The XmlAdapter is referenced using the @XmlJavaTypeAdapter annotation.

    package forum11743306;
    
    import javax.xml.bind.annotation.*;
    import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
    import javax.xml.datatype.XMLGregorianCalendar;
    
    @XmlRootElement
    public class Root {
    
        private XMLGregorianCalendar xyzDate;
    
        @XmlElement(name = "XYZDate", required=true, nillable = true)
        @XmlJavaTypeAdapter(DateAdapter.class)
        public XMLGregorianCalendar getXyzDate() {
            return xyzDate;
        }
    
        public void setXyzDate(XMLGregorianCalendar xyzDate) {
            this.xyzDate = xyzDate;
        }
    
    }
    

    Option #2 - Using MOXy's @XmlNullPolicy Extension

    MOXy offers an @XmlNullPolicy extension that gives you some flexibility in how you represent null.

    package forum11743306;
    
    import javax.xml.bind.annotation.*;
    import javax.xml.datatype.XMLGregorianCalendar;
    
    import org.eclipse.persistence.oxm.annotations.*;
    
    @XmlRootElement
    public class Root {
    
        private XMLGregorianCalendar xyzDate;
    
        @XmlElement(name = "XYZDate", required=true, nillable = true)
        @XmlNullPolicy(emptyNodeRepresentsNull = true, nullRepresentationForXml = XmlMarshalNullRepresentation.EMPTY_NODE)
        public XMLGregorianCalendar getXyzDate() {
            return xyzDate;
        }
    
        public void setXyzDate(XMLGregorianCalendar xyzDate) {
            this.xyzDate = xyzDate;
        }
    
    }
    

    Other Files

    The following files can be used with either option to complete the example.

    jaxb.properties

    To specify MOXy as your JAXB provider you need to include a file called jaxb.properties in the same package as your domain model with the following entry (see: http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html).

    javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
    

    Demo

    package forum11743306;
    
    import javax.xml.bind.*;
    import javax.xml.datatype.DatatypeFactory;
    
    import org.eclipse.persistence.Version;
    
    public class Demo {
    
        public static void main(String[] args) throws Exception {
            JAXBContext jc = JAXBContext.newInstance(Root.class);
            System.out.println(Version.getVersion());
            System.out.println(jc.getClass());
    
            Marshaller marshaller = jc.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
    
            Root root = new Root();
            root.setXyzDate(null);
            marshaller.marshal(root, System.out);
    
            root.setXyzDate(DatatypeFactory.newInstance().newXMLGregorianCalendar("2012-08-01"));
            marshaller.marshal(root, System.out);
        }
    
    }
    

    Output

    2.4.0
    class org.eclipse.persistence.jaxb.JAXBContext
    
    
       
    
    
    
       2012-08-01
    
    

提交回复
热议问题