You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在无中间容器类的情况下用JAXB映射多类型对象列表?

问题与解决方案

现有XML Schema

<xs:element name="document" type="Document"/>

<xs:complexType name="Document">
    <xs:sequence>
        <xs:element name="description" type="xs:string" minOccurs="0"/>
        <xs:element name="destination" type="xs:string" minOccurs="0"/>
        <xs:element name="tags" type="TagList" minOccurs="0"/>
    </xs:sequence>
</xs:complexType>

<xs:complexType name="TagList">
    <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:any processContents="lax" namespace="http://www.example.com/schema/tags"/>
    </xs:choice>
</xs:complexType>

对应XML结构

<document>
  <description>the description</description>
  <destination>the destination</destination>
  <tags>
    <tagA>
      <propA1>...</propA1>
      <propA2>...</propA2>
      ...
    </tagA>
    <tagB>
      <propB1>...</propB1>
      <propB2>...</propB2>
      ...
    </tagB>
    ...
  </tags>
</document>

其中tags节点包含0个或多个来自独立Schema定义的不同类型标签元素。

当前xjc生成的Java类

使用xjc工具生成的代码如下,需通过document.getTags().getAny()访问标签项:

public class Document {
  private String description;
  private String destination;
  private TagsList tags;
  // getter/setter
}

public class TagsList {
  private List<Object> any;
  // getter/setter
}

需求

希望生成的Document类直接包含List<Object>类型的tags字段,如下所示:

public class Document {
  private String description;
  private String destination;
  private List<Object> tags;
  // getter/setter
}

注:将TagList中的choice改为sequence无效果。


解决方案

方法1:内联复杂类型定义到Schema中

修改XML Schema,将TagList的复杂类型定义直接内联到Document的tags元素里,避免生成单独的TagList类:

<xs:element name="document" type="Document"/>

<xs:complexType name="Document">
    <xs:sequence>
        <xs:element name="description" type="xs:string" minOccurs="0"/>
        <xs:element name="destination" type="xs:string" minOccurs="0"/>
        <xs:element name="tags" minOccurs="0">
            <xs:complexType>
                <xs:choice minOccurs="0" maxOccurs="unbounded">
                    <xs:any processContents="lax" namespace="http://www.example.com/schema/tags"/>
                </xs:choice>
            </xs:complexType>
        </xs:element>
    </xs:sequence>
</xs:complexType>

重新运行xjc后,会直接在Document类中生成List<Object> tags字段,无需中间的TagList类。

方法2:使用JAXB自定义绑定文件

如果无法修改原始Schema,可以创建绑定文件(例如bindings.xjb),通过JAXB的绑定规则将TagList的内容内联到Document的tags属性:

<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" version="2.1"
               xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <jaxb:bindings schemaLocation="你的Schema文件路径.xsd">
        <!-- 定位到Document类中的tags元素 -->
        <jaxb:bindings node="//xs:complexType[@name='Document']//xs:element[@name='tags']">
            <jaxb:property>
                <!-- 内联复杂类型,直接生成List<Object>类型的属性 -->
                <jaxb:inline/>
            </jaxb:property>
        </jaxb:bindings>
    </jaxb:bindings>
</jaxb:bindings>

运行xjc时指定该绑定文件:

xjc -b bindings.xjb 你的Schema文件路径.xsd

两种方法都能生成符合需求的Document类,直接通过document.getTags()获取标签列表。


内容的提问来源于stack exchange,提问作者Gaetan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 01:50:31