How I can remove null values and keys from JSON using cobol statments- V6.1 COBOL ENTERPRISE

Viewed 1005

I can't figure out how to remove null values (and corresponding keys) from the output JSON.

Using JSON GENERATE, I am creating JSON output and in output I am getting \U0000 as null.

I want to identify and remove null values and keys from the JSON.

Cobol version - 6.1.0

I am generating a file with PIC X(5000). Tried INSPECT and other statements but no luck :(

For example :

    {
        "Item": "A",
        "Price": 12.23,
        "Qty": 123
      },
      {
        "Item": "B",
        "Price": \u000,
        "Qty": 234
      },
      {
        "Item": "C",
        "Price": 23.2,
        "Qty": \u0000
      }

In output I want:

    {
        "Item": "A",
        "Price": 12.23,
        "Qty": 123
      },
      {
        "Item": "B",
        "Qty": 234
      },
      {
        "Item": "C",
        "Price": 23.2,
      }

Approach 1:

  • created JSON using JSON GENERATE command and defined output file in PIC X(50000).
  • after converting to UTF-8 trying to use INSPECT to find the '\U000' using hex value but there is no effect on UTF8 arguments and not able to search '\U000' values.
perform varying utf-8-pos from 1 by 1 
   until utf-8-pos = utf-8-end 
   EVAUATE TRUE 
    WHEN JSONOUT(1:utf-8-pos) = X'5C'    *> first finding a "\" value in o/p
      perform varying utf-8-pos from 1 by 1
          until JSONOUT(1:utf-8-pos)  = x'22'   *> second finding a end position string " as X'22' 
               move JSONOUT(1: utf-8-end - utf-8-pos) to JSONOUT     *> skip the position of null
      end-perform
    WHEN JSONOUT(1:utf-8-pos) NOT= X'5C'
      continue
    WHEN OTHER
      continue 
   END-EVALUATE
end-perform     

Approach 2:

  • Convert the item to UTF-16 in a national data item by using NATIONAL-OF function.
  • using INSPECT, EVALUATE OR PERFORM to find '\U000' using hex value N'005C'. but not able to find the correct position of '\u000' also tried NX'005C' to find but no luck.
IDENTIFICATION DIVISION.
PROGRAM-ID.   JSONTEST.

ENVIRONMENT DIVISION.
CONFIGURATION SECTION.

SOURCE-COMPUTER. IBM-370-158.

DATA DIVISION.

WORKING-STORAGE SECTION.

  01 root.
   05 header.
     10 systemId       PIC X(10).
     10 timestamp      PIC X(30).
   05 payload.
     10 customerid         PIC X(10).
  
  77 Msglength   PIC 9(05).
  77 utf-8-pos   PIC 9(05).
  77 utf-8-end   PIC 9(05).

01 jsonout    PIC X(30000).

PROCEDURE DIVISION.

MAIN SECTION.

    MOVE "2012-12-18T12:43:37.464Z"   to   timestamp
    MOVE LOW-VALUES                   to   customerid
    JSON GENERATE jsonout
         FROM root
       COUNT IN Msglength
       NAME  OF root is OMITTED 
                systemId IS 'id'
      ON EXCEPTION
         DISPLAY 'JSON EXCEPTION'
         STOP RUN
   END-JSON
   
   DISPLAY jsonout (1:Msglength)
   
   PERFORM skipnull.

MAIN-EXIT.
 EXIT.


Skipnull SECTION.

perform varying utf-8-pos from 1 by 1 
   until utf-8-pos = utf-8-end 
   EVALUATE TRUE 
    WHEN JSONOUT(1:utf-8-pos) = X'5C' *> first finding a "\" value in o/p
      perform varying utf-8-pos from 1 by 1
          until JSONOUT(1:utf-8-pos)  = x'22'   *> second finding a end position string " as X'22' 
               move JSONOUT(1: utf-8-end - utf-8-pos) to JSONOUT   *> skip the position of null
      end-perform
    WHEN JSONOUT(1:utf-8-pos) NOT= X'5C'
      continue
    WHEN OTHER
      continue 
   END-EVALUATE
end-perform.

Skipnull-exit.
EXIT.

sample output : As we don't have any value to fill for customer id so in o/p results we are getting :

{"header" : {
   "timestamp" : "2012-12-18T12:43:37.464Z",
   "customerid" : "\u0000\u0000\u00000"   }
}

in result I want to skip customerid from the o/p. I want to skip both object:Name from the o/p file.

2 Answers

Since Enterprise COBOL's JSON GENERATE is an all-in-one-go command I don't think there's an easy way to do this in V6.1.

Just to give you something to look forward to: Enterprise-COBOL 6.3 offers an extended SUPPRESS-clause that does just what you need:

JSON GENERATE JSONOUT FROM MYDATA COUNT JSONLEN                
     SUPPRESS WHEN ZERO                                           
     ON EXCEPTION DISPLAY 'ERROR JSON-CODE: ' JSON-CODE        
     NOT ON EXCEPTION DISPLAY 'JSON GENERATED - LEN=' JSONLEN  

You can also suppress WHEN SPACES, WHEN LOW-VALUE or WHEN HIGH-VALUE. You can also limit suppression to certain fields:

SUPPRESS Price WHEN ZERO
         Qty   WHEN ZERO

Unfortunately this feature hasn't been backported to 6.1 yet (it's been added to 6.2 with the December 2020 PTF) and I don't know whether it will be...

I don't know anything about cobol but I was need the same thing in javascript, so I will share my javascript function for you. If you can translate this to cobol maybe it will help to you.

function clearMyJson(obj) {
    for (var i in obj) {
        if ($.isArray(obj[i]))
            if (obj[i].length == 0) //remove empty arrays
                delete obj[i];
            else
                clearMyJson(obj[i]);  //calling function for clear the array
        else if ($.isPlainObject(obj[i]))
            if ((obj[i] == null || obj[i] == "")) // delete property if its null or empty
                delete obj[i];
            else
                clearMyJson(obj[i]); //calling function for clear the object 
    }
}
Related