Search code examples
jaxbjaxb2

@XmlTransient marked value returns null when unmarshalling


I am using @XmlTransient for hiding some Strings in output XML file. It works fine while marshalling and the XML is fine.
However when I unmarshall the XML, the @XmlTransient marked values appear as null.


Solution

  • What @XmlTransient Does

    @XmlTransient marks the property as unmapped so it is excluded from both marshalling and unmarshalling.


    What You Could Do

    If you just want to exclude the value from marshalling you may consider using an XmlAdapter

    XmlAdapter (StringAdapter)

    The XmlAdapter will always return "" for the marshal operation and the JAXB implementation will return an empty element. If you are using EclipseLink MOXy as your JAXB implementation you could return null to eliminate the node completely (see: http://blog.bdoughan.com/2012/04/binding-to-json-xml-handling-null.html).

    import javax.xml.bind.annotation.adapters.XmlAdapter;
    
    public class StringAdapter extends XmlAdapter<String, String> {
    
        @Override
        public String marshal(String string) throws Exception {
            return null;
        }
    
        @Override
        public String unmarshal(String string) throws Exception {
            return string;
        }
    
    }
    

    Person

    import javax.xml.bind.annotation.*;
    import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
    
    @XmlRootElement(name="Person")
    @XmlAccessorType(XmlAccessType.FIELD)
    public class Person {
    
        String name;
    
        String address;
    
        @XmlJavaTypeAdapter(StringAdapter.class)
        String password;
    
    }
    

    input.xml

    <Person>
        <name> some name </name>
        <password> some password </password>
        <address> some address </address>
    </Person>
    

    Demo

    import java.io.File;
    import javax.xml.bind.*;
    
    public class Demo {
    
        public static void main(String[] args) throws Exception {
            JAXBContext jc = JAXBContext.newInstance(Person.class);
    
            Unmarshaller unmarshaller = jc.createUnmarshaller();
            File xml = new File("src/forum14231799/input.xml");
            Person person = (Person) unmarshaller.unmarshal(xml);
    
            System.out.println(person.password);
    
            Marshaller marshaller = jc.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.marshal(person, System.out);
        }
    
    }
    

    Output

     some password 
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <Person>
        <name> some name </name>
        <address> some address </address>
        <password></password>
    </Person>