为什么JAXB有时会映射到JAXBElement? [英] Why does JAXB sometimes map to JAXBElement?

查看:157
本文介绍了为什么JAXB有时会映射到JAXBElement?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

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.

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

推荐答案

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

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:

使用替换组:

<?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你解组,比较下面的例子:

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

  • Without any JAXB metada the result will be wrapped in a JAXBElement
  • Using @XmlRootElement eliminates the root level JAXBElement

这篇关于为什么JAXB有时会映射到JAXBElement?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆