我想在基于jaxb的xml文件中读取面向对象的结构。

可以说这是我的xml文件:

    <?xml version="1.0" encoding="utf-8" standalone="yes"?>
    <children xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <child xsi:type="girl">
            <age>12</age>
            <isdancing>true</isdancing>
        </child>
        <child xsi:type="boy">
            <age>10</age>
            <issoccerplayer>true</issoccerplayer>
        </child>
    </children>


子元素是一种包装元素,包括多个子元素。孩子可以是xsi:type指定的男孩或女孩。这两个类具有一些共同的要素(例如年龄)和一些不同的(不包括)要素(例如isdancing或issoccerplayer)

要读取文件,我有以下方法:

    public static void main( String[] args ) throws JAXBException
    {
        JAXBContext jaxbContext;
        jaxbContext = JAXBContext.newInstance(Children.class);
        Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
        File file = new File("C:/test.xml");
        if (!file.exists()) System.out.println("File does not exist");

        Children children = (Children) jaxbUnmarshaller.unmarshal(file);
        System.out.println(children.toString());
    }


我的孩子班级看起来像这样:

    @XmlRootElement(name="children")
    @XmlAccessorType(XmlAccessType.FIELD)
    public class Children {

        @XmlElement(name="child")
        private List<Child> childrenList;

        public List<Child> getChildren() { return childrenList; }
        public void setChildren(List<Child> children) {this.childrenList = children;}

    @Override
        public String toString() {
            return ReflectionToStringBuilder.toString(this);
        }
    }


我的孩子班级看起来像这样:

    @XmlAccessorType(XmlAccessType.FIELD)
    public class Child {

    @XmlAttribute(name="xsi:type")
    private XsiType xsiType;

    private int age;

    @XmlElement(name = "isdancing")
    private boolean isDancing;

    @XmlElement(name = "issoccerplayer")
    private boolean isSoccerPlayer;

        //Getter and setter for all fields

    @Override
    public String toString() {
        return ReflectionToStringBuilder.toString(this);
        }
    }


我的XsiType类看起来像这样:

    @XmlAccessorType(XmlAccessType.FIELD)
    public class XsiType {

        @XmlAttribute(name="xsi:type")
        private String name;

        @XmlValue
        private String value;

        public String getName() { return name; }
        public void setName(String name) { this.name = name; }
        public String getValue() { return value;
        public void setValue(String value) { this.value = value; }
    }


在我的pom.xml中,我包括以下依赖项:

    <dependencies>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.9</version>
        </dependency>
    </dependencies>


我的问题现在是,输出正常,但是Child-class的元素xsiType始终为null,否则它将以IllegalAnnotationExceptions结尾,该异常与XmlTest.model.Child.xsiType相关

所以我期望通过设置任何一种@ Xml-Annotation都会出错。有人可以通过发现错误来帮助我吗?

目标是迭代子列表,并在运行时(基于xsiType)决定是男孩还是女孩。

谢谢

最佳答案

您不需要您的XsiType类。
您可以只使用String代替。

在您的Child课中
xsiType属性应如下所示。

@XmlAttribute(name = "type", namespace = "http://www.w3.org/2001/XMLSchema-instance")
private String xsiType;


注意:在@XmlAttribute批注中


使用name = "type"(不带前缀xsi:
指定XML中给定的namespace参数
xmlns:xsi="..."




顺便说说:
不用输入字符串"http://www.w3.org/2001/XMLSchema-instance"
你最好使用常数
XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI
因此,改进后的代码将如下所示:

@XmlAttribute(name = "type", namespace = XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI)
private String xsiType;

09-08 03:27