COBOL 6.3中用JSON GENERATE抑制数组空值元素的实现方法
COBOL 6.3生成带字段抑制的JSON解决方案
问题描述
需求:使用COBOL 6.3的JSON GENERATE语句,从指定拷贝簿结构生成JSON,要求当model-value(对应ws-inx1、ws-inx2索引的数组元素)值为空格时,不输出该字段。若JSON GENERATE无法实现,求COBOL-CICS程序中其他生成JSON的方式(已查看CICS JSON Assist,未找到字段抑制选项)。
拷贝簿结构
01 payload 03 reference-id pic x(10). 03 model-specific-data occurs 5 times indexed by ws-inx1. 05 model-id pic x(10). 05 model-values occurs 5 times indexed by ws-inx2. 10 model-attrib-name pic x(01). 10 model-value pic x(3). 10 model-value-boolean pic x(05). 88 true-val value 'true'. 88 false-val value 'false'.
期望生成的JSON示例
{ "payload": { "reference-id": "abc123", "model-specific-data": [ { "model-id": "model 01", "model-value-attribs": [ { "model-attrib-name": "a", "model-value": "A01", "model-value-boolean": true }, { "model-attrib-name": "b", "model-value": "123", "model-value-boolean": false }, { "model-attrib-name": "x", "model-value-boolean": false } ] }, { "model-id": "model 02", "model-value-attribs": [ { "model-attrib-name": "c", "model-value": "C01", "model-value-boolean": true }, { "model-attrib-name": "d", "model-value": "D01", "model-value-boolean": false } ] } ] } }
解决方案
一、使用JSON GENERATE实现字段抑制
COBOL 6.3的JSON GENERATE支持通过条件规则实现字段抑制,核心步骤如下:
为目标字段添加抑制条件
修改拷贝簿定义,给model-value字段添加OMIT WHEN子句,指定值为全空格时不输出:01 payload 03 reference-id pic x(10). 03 model-specific-data occurs 5 times indexed by ws-inx1. 05 model-id pic x(10). 05 model-values occurs 5 times indexed by ws-inx2. 10 model-attrib-name pic x(01). 10 model-value pic x(3) OMIT WHEN (model-value = spaces). 10 model-value-boolean pic x(05) FORMAT BOOLEAN 88 true-val value 'true'. 88 false-val value 'false'.FORMAT BOOLEAN:将PIC X类型的布尔字符串自动转换为JSON原生布尔值(true/false)
标记数组有效元素数量
JSON GENERATE默认会输出数组的全部5个元素,需先遍历数组统计有效元素数量,再通过COUNT子句控制输出范围:*> 统计model-specific-data的有效元素数 INITIALIZE ws-msd-count TO 0 PERFORM VARYING ws-inx1 FROM 1 BY 1 UNTIL ws-inx1 > 5 IF model-id(ws-inx1) NOT = spaces ADD 1 TO ws-msd-count *> 统计当前model-specific-data下model-values的有效元素数 INITIALIZE ws-mv-count(ws-inx1) TO 0 PERFORM VARYING ws-inx2 FROM 1 BY 1 UNTIL ws-inx2 >5 IF model-attrib-name(ws-inx1, ws-inx2) NOT = spaces ADD 1 TO ws-mv-count(ws-inx1) END-IF END-PERFORM END-IF END-PERFORM *> 执行JSON生成 JSON GENERATE ws-json-output FROM payload COUNT model-specific-data BY ws-msd-count COUNT model-values(ws-inx1) BY ws-mv-count(ws-inx1) SUPPRESS OMITTED END-JSONSUPPRESS OMITTED:确保被OMIT WHEN匹配的字段完全不输出,而非输出null
二、JSON GENERATE无法满足时的替代方案
1. 手动拼接JSON字符串
直接通过字符串操作拼接JSON,完全控制字段输出逻辑:
*> 初始化输出字符串 INITIALIZE ws-json-output TO spaces STRING '{"payload": {"reference-id": "'", reference-id, "'", ',"model-specific-data": [' INTO ws-json-output END-STRING *> 遍历model-specific-data数组 PERFORM VARYING ws-inx1 FROM 1 BY 1 UNTIL ws-inx1 > ws-msd-count IF ws-inx1 > 1 STRING ',' INTO ws-json-output DELIMITED SIZE END-IF STRING '{"model-id": "'", model-id(ws-inx1), "'", ',"model-value-attribs": [' INTO ws-json-output END-STRING *> 遍历model-values数组 PERFORM VARYING ws-inx2 FROM 1 BY 1 UNTIL ws-inx2 > ws-mv-count(ws-inx1) IF ws-inx2 > 1 STRING ',' INTO ws-json-output DELIMITED SIZE END-IF STRING '{"model-attrib-name": "'", model-attrib-name(ws-inx1,ws-inx2), "'" INTO ws-json-output END-STRING *> 非空才拼接model-value IF model-value(ws-inx1,ws-inx2) NOT = spaces STRING ',"model-value": "'", model-value(ws-inx1,ws-inx2), "'" INTO ws-json-output END-IF *> 拼接布尔值 IF true-val(ws-inx1,ws-inx2) STRING ',"model-value-boolean": true}' INTO ws-json-output ELSE STRING ',"model-value-boolean": false}' INTO ws-json-output END-IF END-PERFORM STRING ']}' INTO ws-json-output END-PERFORM STRING '}}}' INTO ws-json-output
优点是完全可控,缺点是代码繁琐,需注意JSON语法的引号、逗号匹配。
2. 使用CICS DFHJSON API
CICS提供的DFHJSON系列API支持灵活的JSON转换,可通过条件判断控制字段输出:
*> 初始化JSON转换环境 EXEC CICS JSONINITIALIZE HANDLE(ws-json-handle) SUPPRESS(NULLS) RESP(ws-resp) RESP2(ws-resp2) END-EXEC *> 添加reference-id字段 EXEC CICS JSONADD HANDLE(ws-json-handle) NAME('reference-id') DATA(reference-id) TYPE(CHAR) RESP(ws-resp) RESP2(ws-resp2) END-EXEC *> 处理model-specific-data数组 PERFORM VARYING ws-inx1 FROM 1 BY 1 UNTIL ws-inx1 > ws-msd-count EXEC CICS JSONSTARTARRAY HANDLE(ws-json-handle) NAME('model-specific-data') RESP(ws-resp) RESP2(ws-resp2) END-EXEC EXEC CICS JSONADD HANDLE(ws-json-handle) NAME('model-id') DATA(model-id(ws-inx1)) TYPE(CHAR) RESP(ws-resp) RESP2(ws-resp2) END-EXEC *> 处理model-values数组 EXEC CICS JSONSTARTARRAY HANDLE(ws-json-handle) NAME('model-value-attribs') RESP(ws-resp) RESP2(ws-resp2) END-EXEC PERFORM VARYING ws-inx2 FROM 1 BY 1 UNTIL ws-inx2 > ws-mv-count(ws-inx1) EXEC CICS JSONSTARTOBJECT HANDLE(ws-json-handle) RESP(ws-resp) RESP2(ws-resp2) END-EXEC EXEC CICS JSONADD HANDLE(ws-json-handle) NAME('model-attrib-name') DATA(model-attrib-name(ws-inx1,ws-inx2)) TYPE(CHAR) RESP(ws-resp) RESP2(ws-resp2) END-EXEC *> 非空才添加model-value IF model-value(ws-inx1,ws-inx2) NOT = spaces EXEC CICS JSONADD HANDLE(ws-json-handle) NAME('model-value') DATA(model-value(ws-inx1,ws-inx2)) TYPE(CHAR) RESP(ws-resp) RESP2(ws-resp2) END-EXEC END-IF *> 添加布尔值 IF true-val(ws-inx1,ws-inx2) EXEC CICS JSONADD HANDLE(ws-json-handle) NAME('model-value-boolean') DATA('true') TYPE(BOOLEAN) RESP(ws-resp) RESP2(ws-resp2) END-EXEC ELSE EXEC CICS JSONADD HANDLE(ws-json-handle) NAME('model-value-boolean') DATA('false') TYPE(BOOLEAN) RESP(ws-resp) RESP2(ws-resp2) END-EXEC END-IF EXEC CICS JSONENDOBJECT HANDLE(ws-json-handle) RESP(ws-resp) RESP2(ws-resp2) END-EXEC END-PERFORM EXEC CICS JSONENDARRAY HANDLE(ws-json-handle) RESP(ws-resp) RESP2(ws-resp2) END-EXEC EXEC CICS JSONENDARRAY HANDLE(ws-json-handle) RESP(ws-resp) RESP2(ws-resp2) END-EXEC END-PERFORM *> 生成最终JSON EXEC CICS JSONGENERATE HANDLE(ws-json-handle) DATA(ws-json-output) LENGTH(ws-json-length) RESP(ws-resp) RESP2(ws-resp2) END-EXEC *> 终止转换环境 EXEC CICS JSONTERMINATE HANDLE(ws-json-handle) RESP(ws-resp) RESP2(ws-resp2) END-EXEC
这种方式比手动拼接更可靠,内置处理JSON语法细节,适合CICS环境下的复杂转换场景。
内容的提问来源于stack exchange,提问作者Jijo
相关产品推荐
相关产品推荐

