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

JAXB解析含CDATA标签的XML时csNum值为null的解决方法

解决JAXB读取含CDATA的XML时csNum字段为null的问题

问题原因

当前JAXB默认会把XMLString节点下的CDATA内容视为纯文本,而非可解析的XML结构,因此无法将其映射到LocationsOuter类的locations属性,最终导致csNum字段值为null。

解决方案

方案一:自定义XmlAdapter自动解析CDATA内容

通过实现XmlAdapter,让JAXB自动将CDATA中的XML字符串转换成目标Java对象。

  1. 创建CDATA解析适配器
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import java.io.StringReader;

public class CDATAXmlAdapter extends XmlAdapter<String, LocationsOuter> {
    @Override
    public LocationsOuter unmarshal(String cdataContent) throws Exception {
        // 解析CDATA内的XML字符串为LocationsOuter对象
        JAXBContext context = JAXBContext.newInstance(LocationsOuter.class);
        Unmarshaller unmarshaller = context.createUnmarshaller();
        return (LocationsOuter) unmarshaller.unmarshal(new StringReader(cdataContent));
    }

    @Override
    public String marshal(LocationsOuter value) throws Exception {
        // 若需生成XML时输出CDATA,可在此补充逻辑,当前返回null即可
        return null;
    }
}
  1. 修改GetLocations类的字段注解
    在xmlString字段上添加@XmlJavaTypeAdapter,指定使用上述适配器:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "getLocations")
public class GetLocations implements Serializable {
    private final static long serialVersionUID = 1L;
    
    @XmlElement(name = "XMLString", required = true, nillable = true)
    @XmlJavaTypeAdapter(CDATAXmlAdapter.class) // 绑定适配器
    protected LocationsOuter xmlString;
    
    public LocationsOuter getXMLString() {
        return xmlString;
    }     

    // 其他原有代码...
}

方案二:手动解析CDATA内容

将XMLString的字段类型改为String,在获取内容后手动解析成目标对象。

  1. 修改GetLocations类的字段类型
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "getLocations")
public class GetLocations implements Serializable {
    private final static long serialVersionUID = 1L;
    
    @XmlElement(name = "XMLString", required = true, nillable = true)
    protected String xmlString; // 改为String类型接收CDATA内容
    
    public String getXMLString() {
        return xmlString;
    }     

    // 新增方法手动解析为LocationsOuter
    public LocationsOuter parseXMLString() throws Exception {
        if (xmlString == null) return null;
        JAXBContext context = JAXBContext.newInstance(LocationsOuter.class);
        Unmarshaller unmarshaller = context.createUnmarshaller();
        return (LocationsOuter) unmarshaller.unmarshal(new StringReader(xmlString));
    }

    // 其他原有代码...
}
  1. 使用时手动解析
// 假设已完成JAXB反序列化得到GetLocations对象
GetLocations request = ...;
LocationsOuter locationsOuter = request.parseXMLString();
if (locationsOuter != null && locationsOuter.getLocations() != null) {
    String csNum = locationsOuter.getLocations().getCsNum();
    // 处理csNum
}

注意事项

  • 确保CDATA内的XML结构与LocationsOuter、Locations类的JAXB注解完全匹配,否则会解析失败。
  • 解析过程中需捕获JAXBException等异常,避免程序崩溃。
  • 若需要生成XML时输出CDATA,可在适配器的marshal方法中补充逻辑(比如用<![CDATA[...]]>包裹序列化后的XML字符串)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 14:36:21