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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3658378/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 02:53:35  来源:igfitidea点击:

Why does JAXB sometimes map to JAXBElement?

javajaxbjaxb2

提问by TL Stillman

There is a placeholder answer over at the unofficial guidewith a link to an article which (to me) seems quite unrelated.

非官方指南中有一个占位符答案,其中包含指向(对我而言)似乎完全无关的文章的链接。

I use XJC to generate my JAXB classes and while most of them map to each other as expected, some elements get mapped to JAXBElement<Foo>. This is most annoying for graphs with cycles, where sometimes the parent node of a Foo element will be the JAXBElement<Foo>, which doesn't itself have a parent property, breaking the cycle.

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

I can think of various workarounds, but it would be much nicer if someone could explain this behaviour to me. Why does JAXB sometimes map a <Foo>element to JAXBElement<Foo>instead of Foo?

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

采纳答案by bdoughan

JAXBElement is used to preserve the element name/namespace in use cases where enough information is not present in the object model. The most common occurence is with substitution groups:

JAXBElement 用于在对象模型中没有足够信息的用例中保留元素名称/命名空间。最常见的情况是替换组:

With Substitution Group:

与替换组:

<?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>

Will generate:

会产生:

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

}

Without Substitution Group:

无替代组:

If you remove the substitution group:

如果删除替换组:

<?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>

The following class will be generated:

将生成以下类:

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

}

You may also get a JAXBElement when you unmarshal, compare the following examples:

解组时也可能会得到 JAXBElement,比较以下示例:

回答by Laxman G

To avoid mapping to JAXBElement? I have done this things it work for me :

避免映射到 JAXBElement?我已经完成了对我有用的事情:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
           xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
           jaxb:extensionBindingPrefixes="xjc"
           jaxb:version="2.0">

    <xs:annotation>
       <xs:appinfo>
          <jaxb:globalBindings generateValueClass="false">
           <xjc:simple />
          </jaxb:globalBindings>
       </xs:appinfo>
    </xs:annotation>

</xs:schema>

Save this file in the xml file and supply as binding files.

将此文件保存在 xml 文件中并作为绑定文件提供。

Reference Link

参考链接

Generate JAXB classes using eclipse dont forget to give binding files created with above xml and check "Allow Vendor extensions" as below:

使用 eclipse 生成 JAXB 类不要忘记提供使用上述 xml 创建的绑定文件并检查“允许供应商扩展”,如下所示:

enter image description here

在此处输入图片说明

With changes i am able Get rid of JAXBElement in classes generated xjc for convert xsd to JAXB generated classes.

通过更改,我能够摆脱生成 xjc 的类中的 JAXBElement,以便将 xsd 转换为 JAXB 生成的类。