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

如何将嵌套XML元素内容映射为Map的字符串值?

Jackson XML反序列化:将随机名称元素的子XML内容转为Map字符串值

使用的依赖

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
    <version>2.8.7</version>
</dependency>

需求说明

需要处理如下XML,将其中名称随机的元素(例如<RandomName>,其内部内容也不固定)的元素名作为Map的key,把该元素下的所有XML内容作为字符串值存入Map,实现类似 RandomName -> <metadaten> ... </metadaten> 的映射。

示例XML

<slices>
    <slice>
        <boundedBy>
            <Envelope>
                <axisLabels>Lat Long</axisLabels>
                <srsDimension>2</srsDimension>
                <lowerCorner>-44.975 111.975</lowerCorner>
                <upperCorner>-8.975 130.975</upperCorner>
            </Envelope>
        </boundedBy>
        <local_metadata_key>test123</local_metadata_key>
        <RandomName>
            <metadaten>
                <Kompression>0</Kompression>
                <Komprimierung>0</Komprimierung>
                <Belaubungszustand>3</Belaubungszustand>
                <Bemerkungen>keine</Bemerkungen>
            </metadaten>
        </RandomName>
        <fileReferenceHistory>testfile</fileReferenceHistory>   
    </slice>
</slices>

当前问题

编写了LocalMetadataChild类用于反序列化,但addKeyValue()方法中,只能拿到key为RandomName,而value始终是空字符串。需要让value等于该元素下的完整子XML内容(即<metadaten> ... </metadaten>部分)。

当前代码:

public class LocalMetadataChild {
    
    public static final String LOCAL_METADATA_TAG = "slice";

    private Map<String, String> localMetadataAttributesMap;
    
    private BoundedBy boundedBy;

    @JsonAnySetter
    // NOTE: To map an unknown list of properties, must use this annotation
    public void addKeyValue(String key, String value) {
        this.localMetadataAttributesMap.put(key, value);
    }

    public LocalMetadataChild() {
        this.localMetadataAttributesMap = new LinkedHashMap<>();
        this.boundedBy = new BoundedBy();
    }

    @JsonAnyGetter
    // NOTE: to unwrap the "map" from { "map": { "key": "value" } }, only keep { "key": "value" }
    public Map<String, String> getLocalMetadataAttributesMap() {
        return localMetadataAttributesMap;
    }
    
    public BoundedBy getBoundedBy() {
        return this.boundedBy;
    }

    public void setBoundedBy(BoundedBy boundedBy) {
        this.boundedBy = boundedBy;
    }

    public LocalMetadataChild(Map<String, String> localMetadataAttributesMap, BoundedBy boundedBy) {
        this.localMetadataAttributesMap = localMetadataAttributesMap;
        this.boundedBy = boundedBy;
    }
}

解决方案

问题出在@JsonAnySetter的参数类型:当元素包含子XML结构时,Jackson无法直接将其序列化为String,会默认解析为内部对象,导致传入空字符串。需要修改参数类型为JsonNode,再将其序列化为XML字符串存入Map。

修改后的代码

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;

public class LocalMetadataChild {
    
    public static final String LOCAL_METADATA_TAG = "slice";

    private Map<String, String> localMetadataAttributesMap;
    
    private BoundedBy boundedBy;
    private final XmlMapper xmlMapper;

    @JsonAnySetter
    public void addKeyValue(String key, JsonNode value) throws Exception {
        // 将JsonNode序列化为XML字符串
        String xmlContent = xmlMapper.writeValueAsString(value);
        this.localMetadataAttributesMap.put(key, xmlContent);
    }

    public LocalMetadataChild() {
        this.localMetadataAttributesMap = new LinkedHashMap<>();
        this.boundedBy = new BoundedBy();
        this.xmlMapper = new XmlMapper();
    }

    public LocalMetadataChild(Map<String, String> localMetadataAttributesMap, BoundedBy boundedBy) {
        this.localMetadataAttributesMap = localMetadataAttributesMap;
        this.boundedBy = boundedBy;
        this.xmlMapper = new XmlMapper();
    }

    @JsonAnyGetter
    public Map<String, String> getLocalMetadataAttributesMap() {
        return localMetadataAttributesMap;
    }
    
    public BoundedBy getBoundedBy() {
        return this.boundedBy;
    }

    public void setBoundedBy(BoundedBy boundedBy) {
        this.boundedBy = boundedBy;
    }
}

关键说明

  • 将@JsonAnySetter的第二个参数从String改为JsonNode,保留子元素的完整结构信息。
  • 通过XmlMapper将JsonNode重新序列化为XML字符串,存入Map即可得到目标子XML内容。
  • 若不需要外层包裹节点(仅需<metadaten>部分),可提取JsonNode的子节点后再序列化。

内容的提问来源于stack exchange,提问作者Bằng Rikimaru

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 04:35:26