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

JAXB如何对HashMap<String, HashMap<String, String>>进行编组生成XML

嵌套HashMap生成指定格式XML的可行方案

方案1:自定义JAXB XmlAdapter适配嵌套Map结构

JAXB默认对Map的序列化格式不符合要求的核心原因是默认的Map适配器会生成<entry key="xxx" value="xxx"/>结构,你可以自己实现XmlAdapter来改写序列化逻辑,适配任意深度的嵌套Map:

  • 第一步:定义适配器类,递归处理Map嵌套场景
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Element;
import org.w3c.dom.Document;
import java.util.Map;

public class NestedMapAdapter extends XmlAdapter<Object, Map<String, Object>> {
    @Override
    public Object marshal(Map<String, Object> map) throws Exception {
        Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        Element root = doc.createElement("map");
        buildMapElement(doc, root, map);
        return root;
    }

    private void buildMapElement(Document doc, Element parent, Map<String, Object> map) {
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            Element keyElement = doc.createElement(key);
            if (value instanceof Map) {
                Element innerMap = doc.createElement("map");
                buildMapElement(doc, innerMap, (Map<String, Object>) value);
                keyElement.appendChild(innerMap);
            } else {
                keyElement.setTextContent(value.toString());
            }
            parent.appendChild(keyElement);
        }
    }

    @Override
    public Map<String, Object> unmarshal(Object v) throws Exception {
        // 不需要反序列化可以留空,按需实现
        return null;
    }
}
  • 第二步:在你要序列化的类的Map字段上加上注解,指定使用自定义适配器:
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.util.Map;

@XmlRootElement
public class YourDataWrapper {
    @XmlJavaTypeAdapter(NestedMapAdapter.class)
    private Map<String, Object> data;
    // 按需补充getter、setter方法
}

之后正常调用JAXB的序列化逻辑就能生成你要的格式。

方案2:直接用StAX流式写XML,不需要依赖JAXB

如果不想折腾JAXB的适配逻辑,对性能要求高或者嵌套层级非常深,可以直接用JDK自带的StAX API手写生成,逻辑更直观可控:

import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamWriter;
import java.io.StringWriter;
import java.util.Map;

public class MapToXmlGenerator {
    public String generate(Map<String, Object> rootMap) throws Exception {
        StringWriter sw = new StringWriter();
        XMLStreamWriter writer = XMLOutputFactory.newInstance().createXMLStreamWriter(sw);
        // 写根map标签
        writer.writeStartElement("map");
        writeMapContent(writer, rootMap, "    ");
        writer.writeEndElement();
        writer.flush();
        return sw.toString();
    }

    private void writeMapContent(XMLStreamWriter writer, Map<String, Object> map, String indent) throws Exception {
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            // 写入换行和缩进保证格式工整
            writer.writeCharacters("\n" + indent);
            writer.writeStartElement(key);
            if (value instanceof Map) {
                // 处理嵌套Map场景
                writer.writeCharacters("\n" + indent + "    ");
                writer.writeStartElement("map");
                writeMapContent(writer, (Map<String, Object>) value, indent + "        ");
                writer.writeCharacters("\n" + indent + "    ");
                writer.writeEndElement();
                writer.writeCharacters("\n" + indent);
            } else {
                // 普通值直接写入文本内容
                writer.writeCharacters(value.toString());
            }
            writer.writeEndElement();
        }
        writer.writeCharacters("\n" + indent.substring(0, Math.max(0, indent.length() - 4)));
    }
}

这种方式不需要额外引入第三方依赖,生成的XML格式可以完全自定义,缩进规则也能自行调整。

方案3:用模板引擎生成

如果生成逻辑后续可能经常调整,不想频繁修改Java代码,可以用FreeMarker、Thymeleaf这类模板引擎,提前写好XML模板,把嵌套Map作为参数传入渲染即可,适合需要灵活调整XML结构的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 19:09:00