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

原文 标签 java jaxb jaxb2

the unofficial guide 上有一个占位符答案带有指向(对我而言)似乎完全无关的文章的链接。

我使用 XJC 生成我的 JAXB 类,虽然它们中的大多数按预期相互映射,但有些元素被映射到 JAXBElement<Foo> .这对于带循环的图来说是最烦人的,有时 Foo 元素的父节点将是 JAXBElement<Foo> ,它本身没有父属性,打破了循环。

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

最佳答案

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>

会产生:
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);
    }

}

无替代组:

如果删除替换组:
<?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>

将生成以下类:
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;
    }

}

解码时也可能会得到 JAXBElement,比较以下示例:
  • Without any JAXB metada the result will be wrapped in a JAXBElement
  • Using @XmlRootElement eliminates the root level JAXBElement
  • 关于java - 为什么 JAXB 有时会映射到 JAXBElement?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3658378/

    相关文章:

    java - JDK 中包含的库版本

    java - 从 sharepoint 2010 事件接收器调用 java webservice

    wsdl - JAXB 自定义 - WSDL 和 schemaLocation 中的多个模式

    java - 派生类型作为 XML 消息的一部分

    java - 将 HttpRequest 注入(inject) SOAP 端点

    java - 锁对象应该是易失的(同步块(synchronized block),类的多个实例)吗?

    java - 放掉参数放心

    java - com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException : 3 counts of IllegalAnnotationExceptions

    java - JAXB 和枚举实现接口(interface)

    xml - 对如何根据我的要求使用 JAXB XML 适配器感到困惑