根据标记将XML解析为特定的子类

时间:2016-09-27 01:52:58

标签: java xml jaxb

假设我有这些课程:

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

public class ParentClass {
    private String value;
}

如果我是使用JAXB从XML文件中读取它,我希望XML是这样的:

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

我会像这样装饰我的课程:

@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;
}

现在,假设ParentClass实际上是一个抽象类或接口,我有两个派生自它的子类;类似的东西:

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() { ... }
}

如何使用JAXB和XML将list属性解析为StringSubclassIntSubclass的列表?

也就是说,如果我从XML中读取StringSubclass个元素或IntSubclass个元素,并且能够识别它们是一种或另一种。像这样:

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

有什么办法吗?也许还有其他框架?

由于

1 个答案:

答案 0 :(得分: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;
    }


}