相当简单 XSD 在 JAXBElement 中生成 ObjectFactory 包装根元素 class

Fairly simple XSD generating ObjectFactory wrapping root element class in JAXBElement

我很难理解为什么 XJC 正在生成一个 ObjectFactory 来包装 class 对应于 JAXBElement 包装器中的根元素的实例。

根元素未使用匿名复杂类型。 (在查看此模式时必须小心一点,因为有一对乍一看看起来相同的 complexType 名称,但一个是复数,另一个是单数——例如 optionalParametersTypeoptionalParameterType

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
           xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns="urn:com-mbm-parameters"
           targetNamespace="urn:com-mbm-parameters"
           elementFormDefault="qualified"
           jaxb:version="2.0">
  <xs:element name="parameters" type="parametersType" />

  <xs:complexType name="parametersType">
    <xs:sequence>
      <xs:element name="option-parameters"              type="optionParametersType"             minOccurs="0" maxOccurs="1"/>
      <xs:element name="positional-parameters"          type="positionalParametersType"         minOccurs="0" maxOccurs="1"/>
      <xs:element name="mutually-exclusive-parameters"  type="mutuallyExclusiveParametersType"  minOccurs="0" maxOccurs="1"/>
    </xs:sequence>
    <xs:attribute name="properties-file" type="xs:string" use="optional"/> 
  </xs:complexType>
  <!--

  -->
  <xs:complexType name="optionParametersType">
   <xs:sequence>
      <xs:element name="option-parameter" type="optionParameterType" minOccurs="1" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>
  <!--

  -->
  <xs:complexType name="optionParameterType">
     <xs:sequence>
       <xs:element name="description" type="descriptionType" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
    <xs:attribute name="type" type="xs:string" use="required"/>
    <xs:attribute name="id" type="xs:string" use="required"/>
    <xs:attribute name="name" type="xs:string" use="required"/>
    <xs:attribute name="command-line-name" type="xs:string" use="optional"/>
    <xs:attribute name="default-value" type="xs:string" use="optional"/>
  </xs:complexType>
  <!--

  -->
  <xs:complexType name="positionalParametersType">
    <xs:sequence>
      <xs:element name="positional-parameter" type="positionalParameterType" minOccurs="1" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>
  <!--

  -->
  <xs:complexType name="positionalParameterType">
    <xs:sequence>
      <xs:element name="description" type="descriptionType" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
    <xs:attribute name="type" type="xs:string" use="required"/>
    <xs:attribute name="id" type="xs:string" use="required"/>
    <xs:attribute name="name" type="xs:string" use="required"/>
  </xs:complexType>
  <!--

  -->
  <xs:complexType name="descriptionType">
     <xs:attribute name="forValue" type="xs:string" use="required"/>
  </xs:complexType>
  <!--

  -->
  <xs:complexType name="mutuallyExclusiveParametersType">
    <xs:sequence>
      <xs:element name="mutually-exclusive-parameter-set" type="mutuallyExclusiveParameterSetType" minOccurs="1" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>
  <!--

  -->
  <xs:complexType name="mutuallyExclusiveParameterSetType">
    <xs:sequence>
      <xs:element name="mutually-exclusive-parameter" type="mutuallyExclusiveParameterType" minOccurs="1" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>
  <!--

  -->
  <xs:complexType name="mutuallyExclusiveParameterType">
    <xs:attribute name="id" type="xs:string" use="required"/>
    <xs:attribute name="value" type="xs:string" use="required"/>
  </xs:complexType>
</xs:schema>

这是 ObjectFactory 的片段 returns ParametersType class 的实例:

/**
     * Create an instance of {@link JAXBElement }{@code <}{@link ParametersType }{@code >}}
     * 
     */
    @XmlElementDecl(namespace = "urn:com-mbm-parameters", name = "parameters")
    public JAXBElement<ParametersType> createParameters(ParametersType value) {
        return new JAXBElement<ParametersType>(_Parameters_QNAME, ParametersType.class, null, value);
    }

这是 唯一 地方 JAXBElement 在整个 ObjectFactory, 中使用,所以它不是为了消除两个或更多可能元素的歧义。

知道为什么会发生这种情况以及如何消除使用包装器的需要吗?

你得到 JAXBElement 的顶级元素,在本例中,它是你的 parameters 元素。

基本原理是将类型和元素(您可以将其视为类型的实例)分开。因此,实际上,消除两个或更多可能元素的歧义 - 您可能有 另一个 模式,它具有相同 parametersType 的不同元素。全局元素有时是通过 <xs:element ref="..."/> 引用的,它们可以有替换组等,所以一般总是有 JAXBElement 对全局元素来说并不是完全没有道理。我并不是说这是最好的设计决策,我只是说其中有一些合理性。

要摆脱包装器,请尝试使用 xjc:simple 或自己添加 @XmlRootElement 注释:

  • JAXB xjc:simple binding does not generate @XmlRootElement for base class

但最好不要抗拒它,拥抱它。