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

Java 为什么JAXB有时会映射到JAXBElement?,java,jaxb,jaxb2,Java,Jaxb,Jaxb2,在上面有一个占位符,上面有一个链接,指向一篇(对我来说)似乎毫不相关的文章 我使用XJC来生成我的JAXB类,虽然它们中的大多数按预期相互映射,但一些元素被映射到JAXBElement。这对于具有循环的图来说是最烦人的,其中Foo元素的父节点有时是JAXBElement,它本身没有父属性,从而打破了循环 我可以想出各种解决办法,但如果有人能向我解释这种行为,那就更好了。为什么JAXB有时会将元素映射到JAXBElement而不是Foo?在对象模型中没有足够信息的情况下,JAXBElement用于

在上面有一个占位符,上面有一个链接,指向一篇(对我来说)似乎毫不相关的文章

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


我可以想出各种解决办法,但如果有人能向我解释这种行为,那就更好了。为什么JAXB有时会将
元素映射到
JAXBElement
而不是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>
当您解组时,还可能会得到一个JAXBElement,请比较以下示例:


避免映射到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>

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

参考文献

使用eclipse生成JAXB类别忘了提供使用上述xml创建的绑定文件,并选中“允许供应商扩展”,如下所示:


通过更改,我可以在xjc生成的类中去掉JAXBELENT,以便将xsd转换为JAXB生成的类

看一看explanation@skaffman:嗯?我看不出你的答案与xjc是否选择
JAXBElement
而不是
Foo
@Chris:这在一定程度上取决于源模式中匿名类型或名称类型的选择。谢谢,替换组确实是发生这种情况的地方。那么,在
afterUnmarshal(Unmarshaller u,Object parent)
中,这些可替换类被传递它们自己的JAXBElement作为它们的
父类
?特别是因为似乎没有办法从JAXBElement获取真正的父元素,这似乎是Metro JAXB(JavaSE6中包含的参考实现)中的一个错误。在MOXy JAXB实现()中,将正确的父对象传递给afterUnmarshal方法。
<?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;
    }

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