Modern COBOL Features: JSON, XML, Functions, and Cloud Integration

COBOL has not stood still. IBM Enterprise COBOL for z/OS has received substantial enhancements over the past decade: native JSON and XML processing, an expanded intrinsic function library, improved Unicode support, and integration with modern DevOps toolchains via Zowe and z/OS Connect. Modern COBOL is not just about maintaining legacy systems — it is a viable choice for new business logic where decimal precision and z/OS performance matter.
JSON GENERATE
JSON GENERATE converts a COBOL data structure to a JSON string automatically. The compiler maps COBOL data names to JSON property names using a straightforward transformation: hyphens become hyphens in the JSON key (or are removed based on NAME clause settings).
WORKING-STORAGE SECTION.
01 WS-ACCOUNT-DATA.
05 WS-ACCOUNT-ID PIC X(10) VALUE 'ACC0012345'.
05 WS-CUSTOMER-NAME PIC X(30) VALUE 'SMITH, JOHN'.
05 WS-BALANCE PIC S9(11)V99 COMP-3 VALUE 1250.75.
05 WS-STATUS-CODE PIC X(2) VALUE 'AC'.
05 WS-OPEN-DATE PIC X(10) VALUE '2024-03-15'.
01 WS-JSON-OUTPUT PIC X(500).
01 WS-JSON-LENGTH PIC 9(5) COMP VALUE ZERO.
01 WS-JSON-STATUS PIC 9(5) COMP VALUE ZERO.
PROCEDURE DIVISION.
JSON GENERATE WS-JSON-OUTPUT
FROM WS-ACCOUNT-DATA
COUNT WS-JSON-LENGTH
ON EXCEPTION
MOVE JSON-STATUS TO WS-JSON-STATUS
PERFORM HANDLE-JSON-ERROR
NOT ON EXCEPTION
PERFORM SEND-JSON-RESPONSE
END-JSON.The generated JSON looks like:
{"account-id":"ACC0012345","customer-name":"SMITH, JOHN","balance":1250.75,"status-code":"AC","open-date":"2024-03-15"}COUNT captures the actual number of bytes written. ON EXCEPTION fires if the output field is too small or the data structure contains items that cannot be serialized.
NAME Clause for Custom JSON Keys
JSON GENERATE WS-JSON-OUTPUT
FROM WS-ACCOUNT-DATA
NAME WS-ACCOUNT-ID IS 'accountId'
WS-CUSTOMER-NAME IS 'customerName'
WS-BALANCE IS 'balance'
WS-STATUS-CODE IS 'status'
COUNT WS-JSON-LENGTH
END-JSON.This generates camelCase property names rather than hyphenated ones — matching REST API conventions.
SUPPRESS Clause
Exclude fields containing SPACES, ZERO, or LOW-VALUES from the generated JSON:
JSON GENERATE WS-JSON-OUTPUT
FROM WS-ACCOUNT-DATA
SUPPRESS WHEN ZERO WS-BALANCE
WHEN SPACES WS-STATUS-CODE
COUNT WS-JSON-LENGTH
END-JSON.Fields with zero balance or spaces status are omitted entirely, reducing payload size for sparse records.
JSON PARSE
JSON PARSE reads a JSON document and maps values to COBOL data items:
WORKING-STORAGE SECTION.
01 WS-INPUT-JSON PIC X(1000).
01 WS-PARSE-STATUS PIC 9(5) COMP VALUE ZERO.
01 WS-PAYMENT-DATA.
05 WS-PAY-AMOUNT PIC S9(9)V99 COMP-3.
05 WS-PAY-CURRENCY PIC X(3).
05 WS-PAY-REFERENCE PIC X(20).
05 WS-PAY-ACCOUNT PIC X(10).
PROCEDURE DIVISION.
MOVE '{"amount":500.00,"currency":"USD",
"reference":"TXN-20260120","account":"ACC001"}'
TO WS-INPUT-JSON
JSON PARSE WS-INPUT-JSON
INTO WS-PAYMENT-DATA
NAME WS-PAY-AMOUNT IS 'amount'
WS-PAY-CURRENCY IS 'currency'
WS-PAY-REFERENCE IS 'reference'
WS-PAY-ACCOUNT IS 'account'
ON EXCEPTION
DISPLAY 'JSON PARSE FAILED: ' JSON-STATUS
NOT ON EXCEPTION
PERFORM PROCESS-PAYMENT
END-JSON.The parser maps JSON property names to COBOL fields using the NAME clause. Unmatched properties are silently ignored. Type conversion is automatic — JSON numbers map to COBOL numeric fields, strings to alphanumeric fields.
XML PARSE
COBOL's XML PARSE processes XML documents using a callback model. The parser fires processing procedure events for each XML element:
WORKING-STORAGE SECTION.
01 WS-XML-DOCUMENT PIC X(2000).
01 WS-CURRENT-ELEMENT PIC X(100).
01 WS-ELEMENT-VALUE PIC X(500).
01 WS-ORDER-DATA.
05 WS-ORDER-ID PIC X(20).
05 WS-ORDER-TOTAL PIC S9(9)V99 COMP-3.
05 WS-ORDER-STATUS PIC X(10).
PROCEDURE DIVISION.
MOVE '<order><id>ORD-001</id>
<total>1500.00</total>
<status>CONFIRMED</status></order>'
TO WS-XML-DOCUMENT
XML PARSE WS-XML-DOCUMENT
PROCESSING PROCEDURE XML-HANDLER
ON EXCEPTION
DISPLAY 'XML PARSE ERROR: ' XML-CODE
END-XML.
XML-HANDLER.
EVALUATE XML-EVENT
WHEN 'START-OF-ELEMENT'
MOVE XML-TEXT TO WS-CURRENT-ELEMENT
WHEN 'CONTENT-CHARACTERS'
EVALUATE WS-CURRENT-ELEMENT
WHEN 'id'
MOVE XML-TEXT TO WS-ORDER-ID
WHEN 'total'
MOVE XML-TEXT TO WS-ORDER-TOTAL-DISPLAY
PERFORM CONVERT-TOTAL-TO-COMP3
WHEN 'status'
MOVE XML-TEXT TO WS-ORDER-STATUS
END-EVALUATE
WHEN 'END-OF-ELEMENT'
CONTINUE
END-EVALUATE.XML-EVENT is a special register set by the runtime for each parser event. XML-TEXT contains the current element name or text content. This event-driven model handles any XML depth without knowing the structure in advance.
Expanded Intrinsic Function Catalogue
IBM Enterprise COBOL v6 significantly expanded the intrinsic function library:
Date and Time Functions
*> Get current date/time:
MOVE FUNCTION CURRENT-DATE TO WS-CURRENT-DATETIME.
*> Returns: YYYYMMDDHHMMSSCCUTCOFFSET (21 chars)
*> Format a date:
MOVE FUNCTION FORMATTED-DATE('YYYY-MM-DD' WS-INTEGER-DATE)
TO WS-FORMATTED.
*> Convert between date formats:
MOVE FUNCTION INTEGER-OF-DATE(20260120) TO WS-INT-DATE.
MOVE FUNCTION DATE-OF-INTEGER(WS-INT-DATE) TO WS-ISO-DATE.
*> Day of week (1=Monday through 7=Sunday):
MOVE FUNCTION DAY-OF-INTEGER(WS-INT-DATE) TO WS-DAY-NUM.Mathematical Functions
*> Square root:
COMPUTE WS-STD-DEV = FUNCTION SQRT(WS-VARIANCE).
*> Natural log and exponential:
COMPUTE WS-LOG-VALUE = FUNCTION LOG(WS-INPUT).
COMPUTE WS-EXP-VALUE = FUNCTION EXP(WS-POWER).
*> Absolute value:
COMPUTE WS-ABS = FUNCTION ABS(WS-SIGNED-VALUE).
*> Maximum and minimum across multiple values:
COMPUTE WS-MAX = FUNCTION MAX(WS-A WS-B WS-C WS-D).
COMPUTE WS-MIN = FUNCTION MIN(WS-A WS-B WS-C WS-D).Statistical Functions
*> Mean of table elements:
COMPUTE WS-AVERAGE =
FUNCTION MEAN(WS-SCORE(1) WS-SCORE(2) WS-SCORE(3)).
*> Median:
COMPUTE WS-MEDIAN =
FUNCTION MEDIAN(WS-VALUE(1) WS-VALUE(2) WS-VALUE(3) WS-VALUE(4)).
*> Standard deviation:
COMPUTE WS-STDDEV =
FUNCTION STANDARD-DEVIATION(WS-SAMPLE(1) WS-SAMPLE(2) WS-SAMPLE(3)).String Functions (v6.3+)
*> Replace substring:
MOVE FUNCTION SUBSTITUTE(WS-TEMPLATE '{{NAME}}' WS-CUSTOMER-NAME)
TO WS-MESSAGE.
*> Check if string contains substring:
IF FUNCTION CONTAINS(WS-INPUT-LINE 'ERROR') = 1
PERFORM HANDLE-ERROR-LINE
END-IF.
*> Hexadecimal conversion:
MOVE FUNCTION HEX-OF(WS-BINARY-DATA) TO WS-HEX-STRING.
MOVE FUNCTION HEX-TO-CHAR(WS-HEX-STRING) TO WS-BINARY-DATA.COBOL and Modern DevOps
VS Code with Z Open Editor
IBM's Z Open Editor extension for VS Code brings modern IDE features to COBOL development:
- Syntax highlighting for COBOL, JCL, copybooks, PL/I, and HLASM
- IntelliSense completion for COBOL keywords, paragraphs, and copybook members
- Hover documentation for statements and variables
- On-the-fly syntax error detection without submitting a compile
- Go-to-definition navigation into copybooks
- Codelens showing where paragraphs are called from
This transforms the COBOL development experience from editing in ISPF/Edit to a modern IDE environment while still targeting z/OS.
Git Integration via Zowe
Zowe is an open-source z/OS framework that provides REST APIs for mainframe access. With Zowe CLI:
# Upload COBOL source to z/OS PDS:
zowe zos-files upload file-to-data-set acctproc.cbl "PROD.COBOL.SOURCE(ACCTPROC)"
# Submit a JCL job:
zowe zos-jobs submit local-file build-acctproc.jcl
# Download sysprint output:
zowe zos-jobs view spool-file-by-id JOB12345 SYSPRINT
# List PDS members:
zowe zos-files list members "PROD.COBOL.SOURCE"This enables COBOL to participate in standard Git workflows: source in Git, CI pipeline submits JCL to compile and test, job output checked for return codes.
Jenkins CI/CD for COBOL
A typical Jenkins pipeline for COBOL:
pipeline {
agent any
stages {
stage('Upload Source') {
steps {
sh "zowe zos-files upload file-to-data-set src/ACCTPROC.cbl 'DEV.COBOL.SOURCE(ACCTPROC)'"
}
}
stage('Compile') {
steps {
sh "zowe zos-jobs submit local-file jcl/compile-acctproc.jcl --wait"
}
}
stage('Test') {
steps {
sh "zowe zos-jobs submit local-file jcl/test-acctproc.jcl --wait"
}
}
stage('Deploy') {
when { branch 'main' }
steps {
sh "zowe zos-jobs submit local-file jcl/deploy-acctproc.jcl --wait"
}
}
}
}z/OS Connect: COBOL as a REST API
IBM z/OS Connect EE exposes COBOL programs as REST API endpoints without modifying the COBOL code:
- A COBOL CICS program processes a COMMAREA (the existing program, unchanged)
- z/OS Connect maps an HTTP POST request to the COMMAREA fields
- The response COMMAREA is mapped to a JSON response body
- External clients (mobile apps, microservices, Node.js) call the API with no knowledge of COBOL or CICS
This is the dominant pattern for mainframe modernization without migration: wrap existing COBOL in a REST interface, keep the proven business logic intact.
GnuCOBOL for Local Development
GnuCOBOL is an open-source COBOL compiler that runs on Linux, macOS, and Windows. It implements COBOL 85, COBOL 2002, and large portions of COBOL 2014 and IBM Enterprise COBOL extensions:
# Install on Ubuntu:
sudo apt install gnucobol
# Compile:
cobc -x -free hello.cob -o hello
# Run:
./helloGnuCOBOL cannot run z/OS-specific programs (CICS EXEC, VSAM I/O, RACF calls), but it is excellent for learning COBOL syntax, arithmetic, string handling, file I/O on local datasets, table processing, and subprogram structure. It accelerates the development-test loop before submitting to z/OS.
Conclusion
Modern COBOL is a genuinely contemporary language with JSON and XML support, a rich function library, cloud-integrated tooling, and a clear path to REST API exposure. The COBOL programs running $3 trillion in daily transactions are not frozen in amber — they are compiled with the latest IBM Enterprise COBOL release, integrated with Git-based pipelines, tested with automated frameworks, and increasingly exposed as microservices via z/OS Connect.
If you are entering the mainframe field in 2026, you are learning a language that has a secure future, a talent premium, and a modern development experience. The COBOL Mastery course covers everything in this curriculum from first program to production deployment.
