0

Developing in Java, I would like to marshal an enum to a specific XML structure. Let's say I have a very simple enum like this:

public enum CustomEnum {
    CUSTOM_ENUM_VALUE_1 ("value 1"),
    CUSTOM_ENUM_VALUE_2 ("value 2"),
    CUSTOM_ENUM_VALUE_3 ("value 3");

    private String value;

    CustomEnum(String value) {
        this.value = value;
    }
}

I would like to marhsal to a structure like this:

<custom-enum>
    <key>CUSTOM_ENUM_VALUE_1</key>
    <value>value 1</value>
</custom-enum>

I tried those annotations like this:

@XmlRootElement (name="custom-enum")
public enum CustomEnum {
    CUSTOM_ENUM_VALUE_1 ("value 1"),
    CUSTOM_ENUM_VALUE_2 ("value 2"),
    CUSTOM_ENUM_VALUE_3 ("value 3");

    private String value;

    CustomEnum(String value) {
        this.value = value;
    }

    @XmlElement (name="value")
    public String getValue() {
        return value;
    }

    @XmlElement (name="key")
    public String getName() {
        return name();
    }
}

But it's not working ...

Hyukchan Kwon
  • 382
  • 1
  • 5
  • 20
  • 1
    You need to use custom adapters here. See [this](https://stackoverflow.com/questions/4656992/providing-custom-value-serialization-for-enums-via-jaxb) question. – chinoy Nov 25 '17 at 16:34
  • Yeah but I don't see how do you construct the structure from the overrided "marshal" method of an adapter ... – Hyukchan Kwon Nov 27 '17 at 06:38

1 Answers1

0

You can use an XMLAdapter here as below

The Enum

package com.test.jaxb;

public enum CustomEnum {
    CUSTOM_ENUM_VALUE_1 ("value 1"),
    CUSTOM_ENUM_VALUE_2 ("value 2"),
    CUSTOM_ENUM_VALUE_3 ("value 3");

    private String value;

    CustomEnum(String value) {
        this.value = value;
    }

    public String getValue() {
        return this.value;
    }

    public CustomEnum fromValue(String value) {
        CustomEnum result = null;
        for (CustomEnum enumVal : CustomEnum.values()) {
            if (enumVal.value.equals(value)) {
                result = enumVal;
                break;
            }
        }
        if(result == null) {
            throw new IllegalArgumentException("CustomEnum does not supported for value " + value);
        }
        return result;
    }
}

The POJO equivalent to marshalled form

package com.test.jaxb;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;

@XmlAccessorType(XmlAccessType.FIELD)
public class AdaptedEnum {
    @XmlElement(name="key")
    private String enumName;
    @XmlElement(name="value")
    private String enumvalue;

    public String getEnumName() {
        return enumName;
    }

    public void setEnumName(String enumName) {
        this.enumName = enumName;
    }

    public String getEnumvalue() {
        return enumvalue;
    }

    public void setEnumvalue(String enumvalue) {
        this.enumvalue = enumvalue;
    }

}

The Adapter

package com.test.jaxb;

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

public class Adapter extends XmlAdapter<AdaptedEnum, CustomEnum> {

    @Override
    public AdaptedEnum marshal(CustomEnum arg0) throws Exception {
        AdaptedEnum result = new AdaptedEnum();
        result.setEnumName(arg0.name());
        result.setEnumvalue(arg0.getValue());
        return result;
    }

    @Override
    public CustomEnum unmarshal(AdaptedEnum arg0) throws Exception {
        return CustomEnum.valueOf(arg0.getEnumvalue());
    }


}

The consumer root element

package com.test.jaxb;

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

@XmlRootElement(name="root")
public  class  RootElement {

    private CustomEnum customEnum = CustomEnum.CUSTOM_ENUM_VALUE_1;

    @XmlJavaTypeAdapter(Adapter.class)
    @XmlElement(name="cusom-enum")
    public synchronized CustomEnum getCustomEnum() {
        return customEnum;
    }

    public synchronized void setCustomEnum(CustomEnum customEnum) {
        this.customEnum = customEnum;
    }


}

Test the code

package com.test.jaxb;

import java.io.StringReader;

import javax.xml.bind.JAXB;
import javax.xml.bind.JAXBException;

public class JAXBTester {

    public static void main(String[] args) throws JAXBException {
        JAXB.marshal(new RootElement(), System.out);
        String input = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\r\n" + 
                "<root>\r\n" + 
                "    <cusom-enum>\r\n" + 
                "        <key>CUSTOM_ENUM_VALUE_1</key>\r\n" + 
                "        <value>value 1</value>\r\n" + 
                "    </cusom-enum>\r\n" + 
                "</root>";
        RootElement root = JAXB.unmarshal(new StringReader(input), RootElement.class);
        System.out.println(root.getCustomEnum());

    }

}
chinoy
  • 172
  • 1
  • 13