SimpleXML非必填ElementList触发ValueRequiredException问题咨询
嘿,我之前在使用SimpleXML解析第三方XML的时候,也踩过内联ElementList的坑,尤其是碰到这种明明设了strict=false还抛ValueRequiredException的情况,给你几个实际试过有效的解决方向:
虽然SimpleXML的strict=false参数理论上会忽略非必填字段的缺失,但对内联的ElementList,框架有特殊的校验逻辑——如果你的注解配置没到位,即使全局设了宽松模式,它还是会认为这个列表是必须存在的。
补全ElementList的注解参数
一定要给ElementList显式加上required=false,同时确保内联参数inline=true配置正确,这是最容易忽略的点:@ElementList(inline = true, required = false) private List<Inning> innings;我之前就是没加
required=false,哪怕全局strict=false,框架还是默认把内联列表当成必填项,直接抛了异常。适配XML中空列表的实际结构
要看第三方XML在列表为空时的表现:是完全没有对应的节点,还是存在一个空的容器标签?比如:空列表时是完全没有
<inning>相关标签,还是有个<innings></innings>的空容器
如果是后者,需要给ElementList加上empty=true参数,告诉框架允许空的容器节点:@ElementList(inline = true, required = false, empty = true) private List<Inning> innings;自定义转换器兜底
如果上面的方法都不生效,那就自己写个转换器完全控制解析逻辑,绕过框架的默认校验:public class InningListConverter implements Converter<List<Inning>> { @Override public List<Inning> read(InputNode node) throws Exception { List<Inning> inningsList = new ArrayList<>(); InputNode childNode; // 遍历所有inning节点,存在就解析,不存在就返回空列表 while ((childNode = node.getNext("inning")) != null) { inningsList.add(new Persister().read(Inning.class, childNode)); } return inningsList; } @Override public void write(OutputNode node, List<Inning> value) throws Exception { // 如果你不需要序列化XML,这里可以留空;需要的话再实现写入逻辑 } }然后在字段上绑定这个转换器:
@ElementList(inline = true, required = false) @Convert(InningListConverter.class) private List<Inning> innings;这个方法我亲测有效,完全规避了框架的校验逻辑,自己掌控解析过程。
检查嵌套类的strict设置
还要确认你解析的整个类链中,父类或者嵌套的子实体类有没有正确设置@Root(strict = false),有时候宽松模式没传递下去,也会导致局部字段的校验异常。
优先检查ElementList的required=false配置,这是90%的情况会犯的错;然后根据XML的实际结构调整empty参数;最后用自定义转换器兜底。
内容的提问来源于stack exchange,提问作者Jake

