senzacionale
senzacionale

Reputation: 20916

OBJECT to XML and XML to OBJECT with JAXBContext and Marshaller

    BufferedWriter out = new BufferedWriter(fstream);
    try {
        JAXBContext context = JAXBContext.newInstance(NarociloType.class);

        Marshaller m = context.createMarshaller();
        m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

        m.marshal(parameters, out);
        out.newLine();
    } catch (PropertyException pe) {
        // TODO: Add catch code
        pe.printStackTrace();
    } catch (JAXBException jaxbe) {
        // TODO: Add catch code
        jaxbe.printStackTrace();
    }

but empty types are not stored into XML. For example:

NarociloType.date = null 

but i can not see in xml <date></date>. JAXB marshalling does not create empty element for null values

Can i also change XML to object back with JAXBContext?

Upvotes: 2

Views: 2570

Answers (2)

bdoughan
bdoughan

Reputation: 149017

Note: The following example works in EclipseLink JAXB (MOXy), but not the JAXB reference implementation included in Java SE 6.

If you are using MOXy as your JAXB provider (I'm the tech lead), then you could use an XmlAdapter for this use case.

DateAdatper

import java.util.Date;

import javax.xml.bind.annotation.XmlValue;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import forum235.DateAdapter.AdaptedDate;

public class DateAdapter extends XmlAdapter<AdaptedDate, Date> {

    @Override
    public Date unmarshal(AdaptedDate adaptedDate) throws Exception {
        return adaptedDate.date;
    }

    @Override
    public AdaptedDate marshal(Date date) throws Exception {
        AdaptedDate adaptedDate = new AdaptedDate();
        adaptedDate.date = date;
        return adaptedDate;
    }

    static class AdaptedDate {
        @XmlValue
        public Date date;
    }

}

Root

import java.util.Date;

import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlRootElement
public class Root {

    private Date date;

    @XmlJavaTypeAdapter(DateAdapter.class)
    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

}

Demo

import java.util.Date;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Root.class);
        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

        Root root = new Root();
        marshaller.marshal(root, System.out);

        root.setDate(new Date());
        marshaller.marshal(root, System.out);
    }

}

Output

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <date/>
</root>
<?xml version="1.0" encoding="UTF-8"?>
<root>
   <date>2011-06-16T09:16:09.452</date>
</root>

jaxb.properties

You use MOXy as your JAXB provider you need to provide a file called jaxb.properties in the same package as your domain classes with the following entry:

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

For More Information on XmlAdapter

Upvotes: 1

lexicore
lexicore

Reputation: 43671

Upvotes: 0

Related Questions