为什么JAXB有时会映射到JAXBElement?

TL *_*man 17 java jaxb jaxb2

非官方指南中有一个占位符回答,其中包含一篇文章的链接(对我而言)似乎非常不相关.

我使用XJC生成我的JAXB类,虽然它们中的大多数按预期映射到彼此,但是一些元素被映射到JAXBElement<Foo>.对于具有循环的图形来说,这是最令人讨厌的,其中有时Foo元素的父节点将是JAXBElement<Foo>,它本身不具有父属性,从而打破了循环.

我可以想到各种解决方法,但如果有人能够向我解释这种行为会更好.为什么JAXB有时会将<Foo>元素映射到JAXBElement<Foo>Foo而不是?

bdo*_*han 10

JAXBElement用于在对象模型中不存在足够信息的用例中保留元素名称/命名空间.最常见的事件是替换组:

与替代组织:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="http://www.example.org" 
    xmlns="http://www.example.org" 
    elementFormDefault="qualified">

    <xs:element name="root">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="anElement"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="anElement" type="xs:string"/>

    <xs:element name="aSubstituteElement" type="xs:string" substitutionGroup="anElement"/>

</xs:schema>
Run Code Online (Sandbox Code Playgroud)

会产生:

package org.example;

import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "anElement"
})
@XmlRootElement(name = "root")
public class Root {

    @XmlElementRef(name = "anElement", namespace = "http://www.example.org", type = JAXBElement.class)
    protected JAXBElement<String> anElement;

    public JAXBElement<String> getAnElement() {
        return anElement;
    }

    public void setAnElement(JAXBElement<String> value) {
        this.anElement = ((JAXBElement<String> ) value);
    }

}
Run Code Online (Sandbox Code Playgroud)

没有替换组:

如果删除替换组:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="http://www.example.org" 
    xmlns="http://www.example.org" 
    elementFormDefault="qualified">

    <xs:element name="root">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="anElement"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="anElement" type="xs:string"/>

</xs:schema>
Run Code Online (Sandbox Code Playgroud)

将生成以下类:

package org.example;

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "anElement"
})
@XmlRootElement(name = "root")
public class Root {

    @XmlElement(required = true)
    protected String anElement;

    public String getAnElement() {
        return anElement;
    }

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

}
Run Code Online (Sandbox Code Playgroud)

您可以在解组时获取JAXBElement,比较以下示例: