JAXB unmarshalling based on element's value

Viewed 110

I would like to unmarshall an object using JAXB based on the enum value/string present in the xml. I have several classes inheriting from one abstract class:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlSeeAlso({ InheritingClassOne.class, InheritingClassTwo.class })
public abstract class BasicClass {
    protected String type; //determines class type
    protected String description;
    //getters & setters
}

two examplary subclasses:

@XmlRootElement(name = "someRoot")
@XmlAccessorType(XmlAccessType.FIELD)
public class InheritingClassOne extends BasicClass {
    private String message;
    private Float mark;
    //getters & setters
}

@XmlRootElement(name = "someRoot")
@XmlAccessorType(XmlAccessType.FIELD)
public class InheritingClassTwo extends BasicClass {
    private Integer value;
    //getters & setters
}

I know that JAXB can unmarshall objects based on xsi:type attribute, which I cannot use, since the input xml is stripped from all atributes. I have tried using Moxy @XmlDiscriminatorNode & @XmlDiscriminatorValue, but these seem to work only with attributes and not the element values. I have also seen @XmlElementRef which lets determine the type based on the name of the element, but again, due to some restrictions all elements have to have the same name in input and output xml.

My input xml is:

<someRoot>
    <type>chooseOne</type>
    <message>Message for InheritingClassOne</message>
    <mark>12.3</mark>
</someRoot>

I did not find solution for this problem other than using @XmlJavaAdapter with defined adapter:

public class CustomAdapter extends XmlAdapter<Object, BasicClass> {

    @Override
    public BasicClass unmarshal(Object v) throws Exception {
        //TODO: cast v to Element interface, get to type element value and handle accordingly
        return null;
    }

    @Override
    public Object marshal(BasicClass v) throws Exception {
        //TODO: marshal
        return null;
    }
}

The adapter solution with reading ElementNsImpl child values to get the category seems awful and takes a lot of effort for such task. Are there any solutions that I am missing? Can I somehow change my models (without using xml attributes), so this task is doable?

0 Answers
Related