Java Model
The following Java model will be used for this example:
The following Java model will be used for this example:
package blog.string2element;
public class Customer {
    private String name;
    private String status;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getStatus() {
        return status;
    }
    public void setStatus(String status) {
        this.status = status;
    }
}
XML (input.xml)
<customer>
    <name>Jane Doe</name>
    <GOLD/>
</customer>
XML Adapter
In order to have the value represented as an empty element we will need to have a Class corresponding to each possible String value. Then the XmlAdapter will convert between the String and Object values. We will make use of @XmlElementRef on the Customer's status property so each Status class will need an @XmlRootElement annotation.
package blog.string2element;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class StatusAdapter extends XmlAdapter<StatusAdapter.Status, String> {
    private static final String GOLD = "GOLD";
    private static final String SILVER = "SILVER";
    private static final String BRONZE = "BRONZE";
    @Override
    public String unmarshal(Status v) throws Exception {
        if(Gold.class == v.getClass()) {
            return GOLD;
        } else if(Silver.class == v.getClass()) {
            return SILVER;
        } else if(Bronze.class == v.getClass()) {
            return BRONZE;
        }
        return null;
    }
    @Override
    public Status marshal(String v) throws Exception {
        if(GOLD.equals(v)) {
            return new Gold();
        } else if(SILVER.equals(v)) {
            return new Silver();
        } else if(BRONZE.equals(v)) {
            return new Bronze();
        }
        return null;
    }
    @XmlSeeAlso({Gold.class, Silver.class, Bronze.class})
    public static abstract class Status {
    }
    @XmlRootElement(name=GOLD)
    public static class Gold extends Status {
    }
    @XmlRootElement(name=SILVER)
    public static class Silver extends Status {
    }
    @XmlRootElement(name=BRONZE)
    public static class Bronze extends Status {
    }
}
Annotated Java Model
In our Java model we will annotate the status property with both @XmlElementRef and @XmlAdapter. This will cause the property value to be derived from the @XmlRootElement values of the adapted classes.
package blog.string2element;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@XmlRootElement
public class Customer {
    private String name;
    private String status;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @XmlElementRef
    @XmlJavaTypeAdapter(StatusAdapter.class)
    public String getStatus() {
        return status;
    }
    public void setStatus(String status) {
        this.status = status;
    }
} Demo Code
The following code can be used to demonstrate the solution.
package blog.string2element;
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
public class Demo {
    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Customer.class);
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("input.xml");
        Customer customer = (Customer) unmarshaller.unmarshal(xml);
        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(customer, System.out);
    }
} Further Reading
If you enjoyed this post, then you may also like:
- The following posts are about @XmlAdapter:
 - The following post is about @XmlElementRef:
 
Thanks for the information
ReplyDeletehttp://owntechnology.blogspot.com
how to add annotation to the status property in auto generated classes. We are generating the classes using xjc command.
ReplyDelete