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

使用XStream转换类反序列化两种XML模式未达预期的技术问题

XStream反序列化XML不符合预期的解决方法

问题场景

使用XStream转换类反序列化两种XML结构时,结果未达预期:

模式1

<value>Hello</value>

模式2

<value>
  <expression>
    map.message
  </expression>
</value>

对应Java模型

@XStreamAlias("value")
@XStreamConverter(value = ToAttributedValueConverter.class, strings = "text")
class ValueNode {

  private String text;

  private ExpressionNode node;
  
  // setter / getter
}

@XStreamAlias("expression")
@XStreamConverter(value = ToAttributedValueConverter.class, strings = "text")
class ExpressionNode {

  private String text;
  
  // setter / getter
}

实际反序列化结果

ValueNode.textValueNode.nodeExpressionNode.text
模式1"Hello"null-
模式2"\n\t\n"null-

预期反序列化结果

ValueNode.textValueNode.nodeExpressionNode.text
模式1"Hello"null-
模式2null实例"map.message"

解决方法

问题核心是ToAttributedValueConverter的特性:它会将节点的所有文本内容(包括空白字符)强制赋值给strings指定字段,同时默认不处理子节点。需按以下方式调整:

1. 移除ValueNode上的ToAttributedValueConverter注解

该注解会干扰子节点的解析,导致模式2中expression节点无法被识别为node字段,反而把空白文本塞给text。修改后:

@XStreamAlias("value")
class ValueNode {

  private String text;

  private ExpressionNode node;
  
  // setter / getter
}

2. 自定义转换器过滤空白文本(可选)

若模式2中value节点的换行、缩进等空白字符导致text被赋值为空字符串,可添加自定义转换器过滤:

public class ValueNodeConverter extends ConverterWrapper {

    public ValueNodeConverter(Converter wrapped) {
        super(wrapped);
    }

    @Override
    public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
        ValueNode node = (ValueNode) super.unmarshal(reader, context);
        // 空白文本直接设为null
        if (node.getText() != null && node.getText().trim().isEmpty()) {
            node.setText(null);
        }
        return node;
    }

    @Override
    public boolean canConvert(Class type) {
        return ValueNode.class.equals(type);
    }
}

注册转换器:

XStream xstream = new XStream();
xstream.processAnnotations(ValueNode.class);
xstream.processAnnotations(ExpressionNode.class);
xstream.registerConverter(new ValueNodeConverter(xstream.getConverter(ValueNode.class)));

3. 保留ExpressionNode的转换器

ExpressionNode上的ToAttributedValueConverter可保留,它能自动忽略expression节点内的空白,将有效文本赋值给text字段。


调整后,两种模式的反序列化结果将完全符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 18:45:05