@XmlAttribute/@XmlValue need to reference a Java type that maps to text in XML

poa picture poa · Sep 26, 2015 · Viewed 8.6k times · Source

how to pick the value of an attribute 'name' which is a PriceEventName class type in the below case, FYI if i put @XmlAttribute above it this is turn out to an exception "an error @XmlAttribute/@XmlValue need to reference a Java type that maps to text in XML" I looking heavily on the internet but I didn't find something similar to my case

PriceEvent class

package somepackage
import ...
import 
@XmlAccessorType(XmlAccessType.FIELD)

    public class PriceEvent {
        @XmlElement(name="Message",namespace="someValue")
        private String color;

        private PriceEventName name;// this is an attribute 
        .
        .
    }

PriceEventName class

Imports ...

public class PriceEventName {

    public static final int PRICEUPDATE_TYPE = 0;
    public static final PriceEventName PRICEUPDATE = new PriceEventName(PRICEUPDATE_TYPE, "X-mas");
    private static java.util.Hashtable _memberTable = init();
    private static java.util.Hashtable init() {
        Hashtable members = new Hashtable();
        members.put("X-mas", PRICEUPDATE);
        return members;
    }

    private final int type;
    private java.lang.String stringValue = null;

        public PriceEventName(final int type, final java.lang.String value) {
        this.type = type;
        this.stringValue = value;
    }

    public static PriceEventName valueOf(final java.lang.String string) {
        java.lang.Object obj = null;
        if (string != null) {
            obj = _memberTable.get(string);
        }
        if (obj == null) {
            String err = "" + string + " is not a valid PriceEventName";
            throw new IllegalArgumentException(err);
        }
        return (PriceEventName) obj;
        }
}

Answer

laune picture laune · Sep 28, 2015

This is how you declare the field as an attribute with an adapter:

@XmlJavaTypeAdapter(PenAdapter.class)
@XmlAttribute 
protected PriceEventName name;
public PriceEventName getName() { return name; }
public void setName(PriceEventName value) { this.name = value; }

Add you'll need to add a getter to PriceEventName:

public String getStringValue(){ return stringValue; }

And here is the adapter class:

import javax.xml.bind.annotation.adapters.XmlAdapter;

public class PenAdapter extends XmlAdapter<String,PriceEventName> {
    public PriceEventName unmarshal(String v) throws Exception {
        return PriceEventName.valueOf( v );
    }
    public String marshal(PriceEventName v) throws Exception {
        return v.getStringValue();
    }
}