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

如何通过XSD定义生成包含HashMap的Java Employee类?

问题描述

我们的应用需要用XML Schema定义(XSD)生成Java类,其中要求用HashMap存储键值对。期望生成的Employee类如下:

public class Employee{
    private String name;
    private Map<String, Object> dataMap;
}

我试过schemagen、JAXBContext等工具,但都没成功。自己编写了下面的XSD定义,不过生成的Java类里dataMap是List类型而非Map,当前使用JDK 1.8,恳请提供解决办法或建议:

<xs:complexType name="employee">
    <xs:sequence>
      <xs:element name="dataMap">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="entry" minOccurs="0" maxOccurs="unbounded">
              <xs:complexType>
                <xs:sequence>
                  <xs:element name="key" minOccurs="0" type="xs:string"/>
                  <xs:element name="value" minOccurs="0" type="xs:anyType"/>
                </xs:sequence>
              </xs:complexType>
            </xs:element>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      <xs:element name="value" type="xs:string" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>

解决方案

JAXB默认不会自动将这种嵌套entry的结构转换成Map,需要通过自定义绑定或适配器来实现,以下是两种可行方法:

方法1:使用JAXB绑定文件(推荐)

创建一个bindings.xjb绑定文件,指定将entry集合转换为Map类型:

<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
               xmlns:xs="http://www.w3.org/2001/XMLSchema"
               jaxb:version="2.1">
    <jaxb:bindings schemaLocation="你的XSD文件名.xsd">
        <!-- 绑定employee类型下的entry元素 -->
        <jaxb:bindings node="//xs:complexType[@name='employee']//xs:element[@name='dataMap']//xs:complexType//xs:sequence//xs:element[@name='entry']">
            <jaxb:property>
                <jaxb:baseType name="java.util.Map&lt;String, Object&gt;"/>
                <jaxb:key node="./xs:complexType/xs:sequence/xs:element[@name='key']"/>
                <jaxb:value node="./xs:complexType/xs:sequence/xs:element[@name='value']"/>
            </jaxb:property>
        </jaxb:bindings>
    </jaxb:bindings>
</jaxb:bindings>

执行xjc命令生成Java类时指定该绑定文件:

xjc -b bindings.xjb 你的XSD文件名.xsd

方法2:手动添加XML适配器

如果已经生成了Java类,可以通过自定义适配器将List转换为Map:

  1. 编写适配器类:
public class EntryListToMapAdapter extends XmlAdapter<List<Entry>, Map<String, Object>> {
    @Override
    public Map<String, Object> unmarshal(List<Entry> entries) throws Exception {
        Map<String, Object> map = new HashMap<>();
        if (entries != null) {
            for (Entry entry : entries) {
                if (entry.getKey() != null) {
                    map.put(entry.getKey(), entry.getValue());
                }
            }
        }
        return map;
    }

    @Override
    public List<Entry> marshal(Map<String, Object> map) throws Exception {
        List<Entry> entries = new ArrayList<>();
        if (map != null) {
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                Entry e = new Entry();
                e.setKey(entry.getKey());
                e.setValue(entry.getValue());
                entries.add(e);
            }
        }
        return entries;
    }
}
  1. 修改生成的Employee类,给dataMap字段添加适配器注解:
public class Employee{
    private String name;
    @XmlJavaTypeAdapter(EntryListToMapAdapter.class)
    private Map<String, Object> dataMap;
    // 此处补充getter、setter方法
}

额外修正

你的XSD中定义的是<xs:element name="value" type="xs:string" minOccurs="0"/>,但期望的Employee类是name字段,记得把XSD里的这个元素名称改成name,否则生成的类里会是value字段而非name。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 22:43:26