原因分析:为何取不到 n_ssdw、c_mc、n_dsrlx
根据你提供的最新日志与代码(7.txt 控制台打印,8.txt 源码),当前版本已经能正确递归展开两层数组,并成功拿到 preservation.cases 下的 c_ah 值。但对于 n_ssdw、c_mc、n_dsrlx 仍然是 null。根本原因在于:
这三个字段实际出现在 decryptedResponse → data → data → civil → cases(数组)→ 每个 case 的 c_dsrxx(数组)→ 每个当事人对象 的内部字段。
你目前的 dataList 模板把这三个字段作为一个“没有 point_index 的根节点”的叶子,且它们的 path 分别只是
n_ssdw、c_mc、n_dsrlx,这会被当作“从 interfaceNode 顶层按绝对路径取值”。自然取不到。正确的取值上下文应当是“civil.cases 的每个元素下的 c_dsrxx 数组的每个对象”,而不在根节点。因此必须:
有一个数组入口字段,指向 decryptedResponse,data,data,civil,cases;
在该入口的子模板下再有一个数组入口字段,指向相对路径 c_dsrxx;
在 c_dsrxx 的子模板里再挂叶子字段 n_ssdw、c_mc、n_dsrlx(相对路径)。
换句话说,模板层级必须对齐 JSON 层级,且每遇到数组就需要一个子模板 point_index 来展开。你现在的模板只覆盖了 lawsuit_person_info.data → detail.preservation.cases → c_ah 这条链,但没有为 civil.cases → c_dsrxx → n_ssdw/c_mc/n_dsrlx 建模。
下面结合你上传内容做具体对照与建议。
1. 现有数据与模板对照
JSON 位置(见 7.txt 中 decryptedResponse 片段):
preservation 路线(你已经打通)
decryptedResponse.data.data.lawsuit_person_info.data[].detail.preservation.cases[].c_ah
civil 路线(你要的 n_ssdw、c_mc、n_dsrlx 在这里)
decryptedResponse.data.data.civil.cases[] 是一个数组
每个 civil.cases[] 元素内有 c_dsrxx[] 是一个数组
c_dsrxx[] 的每项是对象,包含 n_ssdw、c_mc、n_dsrlx 这些字段
你当前 dataList(见 7.txt):
根A:pointIndex=0,list=[ dataAll(pointIndex=109, path=decryptedResponse,data,data,lawsuit_person_info,data) ]
根B:pointIndex=109,list=[ cases1(pointIndex=120, path=detail,preservation,cases), cases2(pointIndex=130, path=detail,civil,cases) ]
模板120:list=[ c_ah(pointIndex=0, path=c_ah) ] → OK,对 preservation.cases 起作用
模板130:list=[ c_dsrxx(pointIndex=20, path=c_dsrxx) ] → 仅到 c_dsrxx 数组入口
最后一个“根”:pointIndex="",list=[ n_ssdw(pointIndex=0, path=n_ssdw), c_mc(...), n_dsrlx(...) ] → 这就是问题的来源。它们不在正确的上下文下。
注意你“详情列表2 cases2”的 path 是 detail,civil,cases,这意味着你是从 lawsuit_person_info.data 的每个元素内部再去 detail.civil.cases。可是在 JSON 中 civil.cases 并不在 lawsuit_person_info.data 的元素里面,而是在 decryptedResponse.data.data.civil.cases 的另一棵树上。也就是说,这条路径根本不属于 lawsuit_person_info.data 每个元素的上下文。你却把它挂在 pointIndex=109 的子字段下面,导致 getByCommaPath(elem, "detail,civil,cases") 返回 null 或不匹配。
这也解释了你输出里 cases2 的 listResult 里 c_dsrxx 的 value 均为 null:路径上下文错了。
2. 直接原因小结
n_ssdw、c_mc、n_dsrlx 取值失败的直接原因:
它们被定义在一个无 point_index 的单独根节点上,使用了“绝对路径 n_ssdw/c_mc/n_dsrlx”,导致在 interfaceNode 顶层取值,路径不对。
即便你在 “详情列表2 cases2” 下定义了 c_dsrxx 的数组入口,但你没有把 n_ssdw、c_mc、n_dsrlx 放到 c_dsrxx 的子模板里;而且 cases2 的路径本身也不在正确的树上(用了 detail,civil,cases)。
3. 应当如何配置 dataList 模板
请将 civil 路线独立成一条链,与 preservation 路线分离,按照 JSON 的绝对路径构建数组入口,不要把 civil.cases 挂在 lawsuit_person_info.data 的子字段下面。一个可行的配置思路:
新增根节点 RootCivil(pointIndex 任意,如 200),它的 list 包含一个字段 CivilCases:
CivilCases: pointIndex=201,path="decryptedResponse,data,data,civil,cases"
新增子模板 TemplateCivilCases(pointIndex=201),它的 list 包含一个子字段 CivilPartyList:
CivilPartyList: pointIndex=202,path="c_dsrxx"
新增子模板 TemplateCivilParty(pointIndex=202),它的 list 包含叶子:
n_ssdw: pointIndex=0,path="n_ssdw"
c_mc: pointIndex=0,path="c_mc"
n_dsrlx: pointIndex=0,path="n_dsrlx"
这样你的代码就会:
从 interfaceNode 根上按绝对路径拿到 civil.cases 数组,遍历元素;
在每个 case 元素上按相对路径 c_dsrxx 拿到内层数组,遍历;
对每个 c_dsrxx 元素,按相对路径取 n_ssdw、c_mc、n_dsrlx 填值。
注意:不要再使用 detail,civil,cases 这种相对路径去访问 civil.cases,因为 civil.cases 不在 lawsuit_person_info.data 的元素里。
4. 代码层面是否还需调整
你当前 8.txt 的代码已经具备多层数组递归能力,核心递归方法 fillFieldListFromJsonNode(...) 已实现且在第一层数组展开时被调用。逻辑上无需再改动,关键在于模板的“路径与层级”要正确。
仅两个小建议,帮助排查与避免误用:
在
fillFieldListFromJsonNode的非叶子分支,如果subFieldJsonNode不是数组,但你预期它应该是数组,建议加一条 debug 输出,便于发现路径上下文错位:} else { System.out.println("[WARN] Non-leaf field expected array but got: " + (subFieldJsonNode == null ? "null" : subFieldJsonNode.getNodeType()) + ", field=" + leafField.getFiledName() + ", path=" + leafField.getPath());}在最外层根循环,给每个
fieldDesc打印下命中的节点类型与数组长度:System.out.println("[ROOT] field=" + fieldDesc.getFiledName() + ", path=" + fieldDesc.getPath() + ", nodeType=" + (fieldJsonNode == null ? "null" : fieldJsonNode.getNodeType()) + (fieldJsonNode != null && fieldJsonNode.isArray() ? (", size=" + fieldJsonNode.size()) : ""));
这样,当你错误地把 civil.cases 作为 lawsuit_person_info 子字段时,你会看到 nodeType=null 或非数组,立刻能定位。
5. 针对你当前输出的几点说明
你现在在 pointIndex=109 的 listResult 里,成功看到了 “详情列表1 cases1 → c_ah 值” 的展开,这是 OK 的;但 “详情列表2 cases2” 下的 c_dsrxx 的 listResult 里,只有 c_dsrxx 这个字段,并且 value 为 null,说明代码确实进入了“非叶子数组入口 → 展开 → 子模板”,但是子模板本身只有一个字段 c_dsrxx(pointIndex=20),且你没有继续把 n_ssdw、c_mc、n_dsrlx 这三个叶子放在“pointIndex=20 的子模板”里,因此到子层级时没有任何叶子可赋值,导致 listResult 里只有空壳。
更关键的是 cases2 的 path 配置错误(detail,civil,cases),导致它是在错误的上下文下寻找 civil.cases。正确应为从 interfaceNode 根的绝对路径 decryptedResponse,data,data,civil,cases 作为一个独立的根入口展开,而不是挂在 109 的子字段下。
6. 最终可执行检查清单
模板/dataList 层级检查
是否存在一个“civil.cases”的独立数组入口字段,path 为 decryptedResponse,data,data,civil,cases?
该字段的 pointIndex 是否能在 dataList 中找到同 pointIndex 的子模板节点?
在 civil.cases 的子模板中,是否有一个字段 path="c_dsrxx",其 pointIndex 指向“c_dsrxx 子模板”?
在 c_dsrxx 子模板中,是否有叶子字段 n_ssdw、c_mc、n_dsrlx,pointIndex=0,path 分别为 n_ssdw、c_mc、n_dsrlx?
代码打印
在根层对 civil.cases 字段打印 nodeType=ARRAY 且 size>0;
在递归层对 c_dsrxx 打印 nodeType=ARRAY 且 size>0;
在最内层叶子赋值时打印命中值。
只要以上几点成立,你就可以像现在拿到 c_ah 一样正常拿到 n_ssdw、c_mc、n_dsrlx。
7. 结论
不是代码递归能力的问题,而是模板的路径和层级设计不匹配 JSON 的实际位置。
将 civil.cases 的入口与 lawsuit_person_info.data 的路线解耦,使用从 interfaceNode 根开始的绝对路径作为 civil.cases 的根入口;在其下再挂 c_dsrxx 数组入口及叶子字段,即可正确填充 n_ssdw、c_mc、n_dsrlx。