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

XMLMapper反序列化AIML混写内容报Expected END_ELEMENT错误如何解决?

问题原因

你遇到的报错本质是Jackson XML模块默认不支持XML混合内容(同一标签内同时存在文本节点和子元素节点)的解析场景。你当前使用的@JacksonXmlText注解仅能捕获标签下的纯文本内容,一旦标签内同时出现子标签,解析器预期读取结束标签时实际读取到子标签的开始标签,就会抛出Expected END_ELEMENT, got event of type 1错误。

解决方案

方案1:使用@JacksonXmlMixed注解适配混合内容(推荐)

这个注解是Jackson XML专门为混合内容场景提供的能力,只需修改Srai类的定义即可:

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlMixed;
import java.util.ArrayList;
import java.util.List;

@JacksonXmlRootElement(localName = "srai")
public class Srai {
    // 用混合内容注解接收所有节点,包括文本节点和子元素节点
    @JacksonXmlMixed
    @JacksonXmlElementWrapper(useWrapping = false)
    private List<Object> content = new ArrayList<>();

    public Srai() {}

    // 原有getText方法改成遍历content提取所有字符串
    public String getText() {
        StringBuilder sb = new StringBuilder();
        for (Object o : content) {
            if (o instanceof String) {
                sb.append((String) o);
            }
        }
        return sb.toString().trim();
    }

    // 原有getStars方法改成遍历content提取所有Star对象
    public List<Star> getStars() {
        List<Star> stars = new ArrayList<>();
        for (Object o : content) {
            if (o instanceof Star) {
                stars.add((Star) o);
            }
        }
        return stars;
    }

    public List<Object> getContent() {
        return content;
    }

    public void setContent(List<Object> content) {
        this.content = content;
    }
}

该方案优势是无需修改上层调用逻辑,原有调用getText()和getStars()的代码可以完全复用,适配所有srai标签的内容场景。

方案2:自定义Srai反序列化器

如果不想改动现有Srai类的字段结构,可以自定义反序列化逻辑手动解析节点:

  1. 编写自定义反序列化器
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import java.io.IOException;
import java.util.ArrayList;

public class SraiDeserializer extends StdDeserializer<Srai> {
    public SraiDeserializer() {
        super(Srai.class);
    }

    @Override
    public Srai deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        Srai srai = new Srai();
        List<Star> stars = new ArrayList<>();
        StringBuilder text = new StringBuilder();
        while (p.nextToken() != JsonToken.END_OBJECT) {
            if (p.currentToken() == JsonToken.VALUE_STRING) {
                text.append(p.getText());
            } else if (p.currentToken() == JsonToken.START_OBJECT && "star".equals(p.currentName())) {
                stars.add(p.readValueAs(Star.class));
            }
        }
        srai.setText(text.toString().trim());
        srai.setStars(stars);
        return srai;
    }
}
  1. 给Srai类绑定反序列化器
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;

@JacksonXmlRootElement(localName = "srai")
@JsonDeserialize(using = SraiDeserializer.class)
public class Srai {
    // 原有字段、getter、setter完全保留不需要改动
}

该方案优势是完全保留原有实体类结构,适合不能改动字段定义的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 06:09:02