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

如何通过JAXB绑定将XSD空复杂类型TextType替换为String类型?

问题描述

必须使用一份不可修改的WSDL,其中定义了无任何元素的复杂类型TextType,但该类型实际应作为简单String类型使用(仅在单独文档中有说明):

<xs:complexType name="TextType">
</xs:complexType>

TextType在XSD中被用于AnschriftType:

<xs:complexType name="AnschriftType">
  <xs:element name="Strasse" type="TextType"/>
</xs:complexType>

JAXB默认生成的POJO中,AnschriftType的strasse字段类型为TextType(空类),希望将其替换为java.lang.String,但尝试两种绑定方式均失败:

尝试方案1:指定class和implClass

<jaxb:bindings node="xs:complexType[@name='TextType']">
    <jaxb:class name="String" implClass="java.lang.String"/>
</jaxb:bindings>

生成的AnschriftType出现错误:getter返回自定义包下的String类,而非java.lang.String:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "AnschriftType" propOrder={...})
public class AnschriftType {

    @XmlElement(name = "Strasse", type = java.lang.String.class)
    protected java.lang.String strasse;

    public package.of.xsd.String getStrasse() {
        return strasse;
    }

    public void setStrasse(package.of.xsd.String value) {
        this.strasse = ((java.lang.String) value);
    }
}

尝试方案2:指定property的baseType

<jaxb:bindings node="xs:complexType[@name='TextType']">
    <jaxb:property>
        <jaxb:baseType name="java.lang.String"/>
    </jaxb:property>
</jaxb:bindings>

生成的POJO无变化,仍使用TextType作为字段类型。


解决方案

要让JAXB直接将TextType映射为java.lang.String,需要结合引用已有类和XML适配器处理空复杂类型与简单字符串的转换,具体步骤如下:

1. 编写XML适配器类

创建适配器类,用于在XML文本内容和String之间做透传转换(因TextType是空复杂类型,实际XML中对应简单文本节点):

package com.yourpackage;

import javax.xml.bind.annotation.adapters.XmlAdapter;

public class TextTypeAdapter extends XmlAdapter<String, String> {
    @Override
    public String unmarshal(String v) throws Exception {
        return v;
    }

    @Override
    public String marshal(String v) throws Exception {
        return v;
    }
}

2. 配置JAXB绑定文件

创建绑定文件(如bindings.xjb),指定TextType引用java.lang.String并使用上述适配器:

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

    <!-- 将TextType直接映射为java.lang.String,使用适配器处理XML转换 -->
    <jaxb:bindings node="xs:complexType[@name='TextType']">
        <jaxb:class ref="java.lang.String"/>
        <jaxb:javaType adapter="com.yourpackage.TextTypeAdapter" name="java.lang.String"/>
    </jaxb:bindings>

    <!-- 确保使用TextType的字段也映射为String -->
    <jaxb:bindings node="xs:complexType[@name='AnschriftType']/xs:element[@name='Strasse']">
        <jaxb:property>
            <jaxb:baseType name="java.lang.String"/>
        </jaxb:property>
    </jaxb:bindings>
</jaxb:bindings>

3. 生成POJO

使用xjc命令并指定绑定文件生成代码:

xjc -b bindings.xjb your-schema.xsd

生成的AnschriftType会直接使用String类型:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "AnschriftType", propOrder = {
    "strasse"
})
public class AnschriftType {

    @XmlElement(name = "Strasse", required = true, type = String.class)
    @XmlJavaTypeAdapter(TextTypeAdapter.class)
    protected String strasse;

    public String getStrasse() {
        return strasse;
    }

    public void setStrasse(String value) {
        this.strasse = value;
    }
}

失败原因说明

  • 方案1中name="String"会让JAXB在当前包下生成新的String类,而非引用java.lang.String,需改用ref属性指定已有类。
  • 方案2的jaxb:property绑定仅针对属性,无法修改复杂类型本身的映射逻辑,因此无法生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 15:55:04