Parse the XML into a specific subclass according to the tag

Suppose I have these classes:

public class Container {
    private String name;
    private int number;
    private List<ParentClass> list;
}

public class ParentClass {
    private String value;
}

If I read it from an XML file using JAXB, I would expect the XML to be something like this:

<container>
    <name>Name</name>
    <number>1</number>
    <subclass>
        <value>Val</value>
    </subclass>
    <subclass>
        <value>Val2</value>
    </subclass>
    <subclass>
        <value>Val3</value>
    </subclass>
</container>

And I would decorate my classes as follows:

@XmlRootElement(name = "container")
@XmlAccessorType(XmlAccessType.FIELD)
public class Container {
    @XmlElement(name = "name")
    private String name;

    @XmlElement(name = "number")
    private int number;

    @XmlElement(name = "subclass", type = Subclass.class)
    private List<ParentClass> list;
}

@XmlRootElement(name = "container")
@XmlAccessorType(XmlAccessType.FIELD)
public class ParentClass {
    @XmlElement(name = "value")
    private String value;
}

Now suppose it ParentClasswas actually an abstract class or interface, and I had two subclasses that were derived from it; sort of:

public abstract ParentClass {
    void doSomething();
}

public IntSubclass extends ParentClass {
    private int value;
    public void doSomething() { ... }
}

public StringSubclass extends ParentClass {
    private String value;
    public void doSomething() { ... }
}

How can I use JAXB and XML to parse an attribute listto be a list StringSubclassor IntSubclassaccordingly?

That is, if I were to read elements from StringSubclassor IntSubclassfrom XML and be able to recognize that they are one or the other. Something like that:

<container>
    <name>Name</name>
    <number>1</number>
    <stringSubclass>
        <value>Val</value>
    </stringSubclass>
    <stringSubclass>
        <value>Val2</value>
    </stringSubclass>
    <intSubclass>
        <value>3</value>
    </intSubclass>
</container>

Is there any way? Maybe with a different frame?

thank

+4
1

@XmlElements

Container.class

package jaxb_element_test;

import java.util.List;

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

@XmlRootElement(name = "container")
@XmlAccessorType(XmlAccessType.FIELD)
public class Container {
    @XmlElement(name = "name")
    private String name;

    @XmlElement(name = "number")
    private int number;

    @XmlElements({
            @XmlElement(name="stringSubclass", type=StringSubclass.class),
            @XmlElement(name="intSubclass", type=IntSubclass.class)})
    private List<ParentClass> list;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }

    public List<ParentClass> getList() {
        return list;
    }

    public void setList(List<ParentClass> list) {
        this.list = list;
    }
}

IntSubclass.class

package jaxb_element_test;

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

@XmlAccessorType(XmlAccessType.FIELD)
public class IntSubclass extends ParentClass {

    @XmlElement(name = "value")
    private int value;

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }


}

StringSubclass.class

package jaxb_element_test;

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

@XmlAccessorType(XmlAccessType.FIELD)
public class StringSubclass extends ParentClass{

    @XmlElement(name = "value")
    private String value;

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }


}
+1

Source: https://habr.com/ru/post/1655903/


All Articles