Generating COBOL Structures with XML Syntax

This chapter discusses generating COBOL data structures with XML syntax by means of the command-line utility cbl2xml.

In this Chapter

cbl2xml Functionality

The cbl2xml utility enables you to:

cbl2xml runs at a command prompt, reads a COBOL record, and generates several files. Use the following command-line syntax:

cbl2xml filename
        [-c cpyFile]
        [-x schemaFile]
        [-m mapFile]
        [-p prefix]
        [-d directiveFile]
        [-v validationFile]
        [-noprompt]
        [-nocountin]

Where the parameters are:

filename The input file for cbl2xml.
  • When converting traditional COBOL data structures to COBOL with XML syntax, this is the filename of a COBOL file being read by cbl2xml. It can be a program with the file extension .cbl, or a copyfile with the file extension .cpy.
  • When converting an XML schema to COBOL with XML syntax, this is the filename of an XML schema file being read by cbl2xml. Schema files usually have an .xsd file extension.
cpyFile The filename of a COBOL copyfile (.cpy file). cbl2xml generates this file to contain COBOL with XML syntax extensions. If you do not specify this parameter, cbl2xml names the generated file using the name of the COBOL or copyfile with -cbl2xml appended to it. For example, if you specify a COBOL program file named account.cbl, the default filename for the copyfile containing XML syntax extensions created by cbl2xml is account-cbl2xml.cpy.
schemaFile The filename of a schema file to be created. If you do not specify this parameter, cbl2xml names the schema file the same as the COBOL file, but with an .xsd extension. For example, if you specify a COBOL program file named account.cbl, the default filename for the schema created by cbl2xml is account.xsd.
mapFile The filename of a map file to be created, or the name of an existing map file. The following rules apply:
  • If the map file you specify does not exist, cbl2xml creates a map file based on the information in the specified COBOL file.
  • If the map file you specify does exist, cbl2xml first asks if you want to overwrite it. If you anwer no, it applies the information in the map file to the generated COBOL file. If you answer yes, cbl2xml generates a new map file overwriting the previous contents of that file.

For more information on map files, see the section Mapping COBOL Data to XML Elements.

prefix Specify a prefix to prepend to generated data names. Use this parameter to create data records that are structured the same as the data records in your COBOL file, but that have different data names. This is useful when you want to keep the original data records intact and supply alternative data names for XML use.

The prefix takes the form of a character string. For example, if you specify -p xml-, cbl2xml prepends xml- to the beginning of each data name it generates.

directiveFile If you normally use a Compiler directive file to compile the COBOL program or copyfile you are XML-enabling, specify that directive file each time you use cbl2xml.

For more information on directive files, see the Help topic Compiler Directives.

validationFile The filename of an XML schema or instance document you want to validate. The following rules apply:
  • If you specify a schema, cbl2xml validates that schema based on W3C XML conventions specified at “http://www.w3.org/2001/XMLSchema”, that is, it validates that the schema itself is a valid schema.
  • If you specify an XML instance document, cbl2xml validates that document against the XML schema specified in the document.
-noprompt Specify this argument when you want cbl2xml to overwrite existing files automatically.

Warning: -noprompt overwrites all files generated by cbl2xml, including map files you have edited, and schema files supplied by third parties. Do not use this parameter unless you are sure you want to overwrite these.

-nocountin Specify this argument to prevent the generation of COUNT IN clauses for generated COBOL data items. This option overrides any values specified in a CBL2XML mapping file.

Generating a Copyfile and Schema

You can generate a copyfile with XML syntax extensions and an XML schema from an existing copyfile or COBOL program. You can use the generated copyfile to XML-enable your COBOL program. You can use the generated schema to create an XML document that conforms to the schema and contains data, and use that document as input to your COBOL. Use the following command-line format for cbl2xml to generate the copyfile and the schema:

cbl2xml filename 
        [-c cobolFile]
        [-x schemaFile]
        [-d directiveFile]
        [-nocountin]        

To enable your COBOL program to access XML information that conforms to the schema generated, cbl2xml generates a new record in a separate copyfile. This new record contains the XML syntax extensions necessary for XML operation. The following example assumes that you have not specified the -c or -x parameters:

Example 1: Generated copyfile with XML syntax extensions

cbl2xml takes the following copyfile record contained in the file record.cpy:

01 A-FILE-RECORD.
   05 A-FILE-ITEM PIC XX.

and generates the following XML-enhanced copyfile, filename record-cbl2xml.cpy:

01 a-file-record identified by "a-file-record" 
   count in a-file-record-count.
   02 a-file-item pic X(2) identified by "a-file-item" 
      count in a-file-item-count.

For detailed information on XML syntax extensions, see the chapter XML Syntax Extensions.

To XML-enable your program, you need to either rename record-cbl2xml.cpy to record.cpy, or replace the original record in record.cpy with the record in record-cbl2xml.cpy.

The process of XML-enabling an entire COBOL program is the same as that of XML-enabling a copyfile. In this case, cbl2xml generates a schema and program that contain equivalent information for each record found in the program.

The schema produced by running cbl2xml on record.cpy, record.xsd, is as follows:

Example 2: Generated XML schema from a COBOL file definition

<?xml version="1.0" encoding="utf-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" 
   elementFormDefault="qualified">
   <element name="a-file-record">
      <complexType>
         <sequence>
            <element name="a-file-item">
               <simpleType>
                  <restriction base="string">
                     <length value="2"/>
                  </restriction>
               </simpleType>
            </element>
         </sequence>
      </complexType>
   </element>
</schema>

The following table explains the purpose of each schema tag in the context of the record it represents:

Schema Tag Description
<element name="a-file-record">
This defines the group-level data name A-FILE-RECORD. It serves as the parent element to all elements that define data items contained in the group.
<complexType>
This indicates that the group record has one or more subordinate data items.
<sequence>
This indicates the beginning of the sequence of tags that defines the subordinate record.
<element name="a-file-item">
This defines the data name of the subordinate data item A-FILE-ITEM. We know it is subordinate because this element tag is a child to a parent element tag.
<simpleType>
This indicates that the data item has no subordinate data items.
<restriction base="string">
This defines any restrictions on the data. In this case, the data must be a string, as indicated by the PIC XX clause in the COBOL data record.
<length value="2"/>
This defines the length of the record, which in this case is 2, as defined by the PIC XX in the COBOL data record.

Generating XML-enhanced COBOL from an XML Schema

The schema produced by cbl2xml using the format described in Generating a Copyfile and Schema conforms to your existing COBOL record, and contains element names derived from your COBOL record. In practical application, a schema of this sort is limited because to exchange XML information with another party, you must use element names recognized by the other party. For example, many industries publish industry-standard schemas, which contain a specific set of elements used to exchange information throughout the industry. To generate COBOL records that contain XML syntax extensions that conform to a third-party schema, use the following cbl2xml format:

cbl2xml XMLschema 
                 [-c cobolFile]
                 [-d directiveFile]
                 [-prompt | -noprompt]

In this example, we use a fictional industry-standard schema named widgets.xsd. This schema enables companies to exchange ordering information for the Widget product. The contents of widgets.xsd is as follows:

Example 3: Industry-standard XML schema for "widgets"

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
 elementFormDefault="qualified">
	<xsd:element name="Availability" type="xsd:string"/>
	<xsd:element name="Base_Price" type="xsd:string"/>
	<xsd:element name="Base_Price_And_Unit">
		<xsd:complexType>
			<xsd:sequence>
				<xsd:element ref="Base_Price"/>
				<xsd:element ref="Unit"/>
			</xsd:sequence>
		</xsd:complexType>
	</xsd:element>
	<xsd:element name="Catalogue_Id" type="xsd:int"/>
	<xsd:element name="widgets">
		<xsd:complexType>
			<xsd:sequence>
				<xsd:element ref="Product_Id" minOccurs="0"/>
				<xsd:element ref="Company_Id"/>
				<xsd:element ref="Catalogue_Id"/>
				<xsd:element ref="SKU"/>
				<xsd:element ref="Product_Series" minOccurs="0"/>
				<xsd:element ref="Availability"/>
				<xsd:element ref="Sale"/>
				<xsd:element ref="Base_Price_And_Unit"/>
			</xsd:sequence>
		</xsd:complexType>
	</xsd:element>
	<xsd:element name="Company_Id" type="xsd:int"/>
	<xsd:element name="Product_Id" type="xsd:int"/>
	<xsd:element name="Product_Series" type="xsd:string"/>
	<xsd:element name="SKU" type="xsd:string"/>
	<xsd:element name="Sale" type="xsd:string"/>
	<xsd:element name="Unit" type="xsd:string"/>
</xsd:schema>

cbl2xml reads this schema and generates a copyfile, widgets.cpy, as follows:

Example 4: XML-enabled COBOL generated from widgets.cpy

       01 Widgets identified by "Widgets".
        02 Product-Id PIC X(80) identified by "Product_Id" 
           count in Product-Id-count.
        02 Company-Id PIC X(80) identified by "Company_Id" 
           count in Company-Id-count.
        02 Catalogue-Id PIC X(80) identified by "Catalogue_Id" 
           count in Catalogue-Id-count.
        02 SKU PIC X(80) identified by "SKU" count in SKU-count.
        02 Product-Series PIC X(80) 
            identified by "Product_Series" 
            count in Product-Series-count.
        02 Availability PIC X(80) identified by "Availability" 
           count in Availability-count.
        02 Sale PIC X(80) identified by "Sale" 
           count in Sale-count.
        02 Base-Price-And-Unit 
           identified by "Base_Price_And_Unit" 
           count in Base-Price-And-Unit-count.
         03 Base-Price PIC X(80) 
            identified by "Base_Price" 
            count in Base-Price-count.
         03 Unit PIC X(80) 
            identified by "Unit" 
            count in Unit-count.

You can then include this copyfile in a COBOL program you want to use to send and receive information about widgets.

Mapping COBOL Data to XML Elements

The example shown in the section Generating XML-enhanced COBOL from an XML Schema above generates COBOL data records based on the element names found in the schema. However, you might have an existing COBOL record you want to use specifically to communicate with a third-party schema. To do this, you must create a direct relationship between a COBOL record and the elements of the schema by means of a map file.

Use this format to generate a map file that you can customize.

cbl2xml filename -m mapFile

The process of XML-enabling an application to exchange information with XML documents based on an existing COBOL record and an existing schema is as follows:

  1. Generate a map file using cbl2xml. To produce a new map file, specify a map filename that does not exist. When cbl2xml does not find an existing map file with the name you specify, it generates a new file.
  2. Edit the map file, changing the names of generated elements to element names that exist in the schema you want to use for data exchange.
  3. Rerun cbl2xml using the same format you used in step 1 of this process. However, this time specify the existing, edited map file. When cbl2xml does find a map file of the name you specified, it applies the mappings in the file to the COBOL record.

The remainder of this section explains the details of this process.

If the mapfile you specify does not exist, cbl2xml takes data structures from the COBOL file, translates them into XML, and writes that information into the map file.

For example:

Example 5: COBOL record and XML schema communication

Product_info.cpy contains the following record:

       01  PRODUCT-INFO.
           05 PROD-ID     PIC 9(6).
           05 COMPANY-ID  PIC 9(4).
           05 CATALOG-NUM PIC 9(8).
           05 SKU-REF     PIC X(10).

The following is the element definition from widget.xsd with which you want to communicate:

	<xsd:element name="Widgets">
		<xsd:complexType>
			<xsd:sequence>
				<xsd:element ref="Product_Id" minOccurs="0"/>
				<xsd:element ref="Company_Id"/>
				<xsd:element ref="Catalogue_Id"/>
				<xsd:element ref="SKU"/>
				<xsd:element ref="Product_Series" minOccurs="0"/>
				<xsd:element ref="Availability"/>
				<xsd:element ref="Sale"/>
				<xsd:element ref="Base_Price_And_Unit"/>
			</xsd:sequence>
		</xsd:complexType>
	</xsd:element>

Cbl2xml generates the following map file from product_info.cpy:

Example 6: Generated map file

<?xml version="1.0" encoding="utf-8"?>
<xml-cobol-mapping-file 
   xmlns="http://xml.microfocus.com/schema/xml/v1.0/mfxmlmap.xsd" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
   xsi:schemaLocation=
    "http://xml.microfocus.com/schema/xml/v1.0/mfxmlmap.xsd
    mfxmlmap.xsd">
   <xml-cobol-mapping>
      <cobol-name>product-info</cobol-name>
      <cobol-count-in>true</cobol-count-in>
      <xml-name>product-info</xml-name>
      <xml-type>group</xml-type>
      <xml-attribute>false</xml-attribute>
      <xml-namespace></xml-namespace>
   </xml-cobol-mapping>
   <xml-cobol-mapping>
      <cobol-name>product-info.prod-id</cobol-name>
      <cobol-count-in>true</cobol-count-in>
      <xml-name>prod-id</xml-name>
      <xml-type>string</xml-type>
      <xml-attribute>false</xml-attribute>
      <xml-namespace></xml-namespace>
   </xml-cobol-mapping>
   <xml-cobol-mapping>
      <cobol-name>product-info.company-id</cobol-name>
      <cobol-count-in>true</cobol-count-in>
      <xml-name>company-id</xml-name>
      <xml-type>string</xml-type>
      <xml-attribute>false</xml-attribute>
      <xml-namespace></xml-namespace>
   </xml-cobol-mapping>
   <xml-cobol-mapping>
      <cobol-name>product-info.catalog-num</cobol-name>
      <cobol-count-in>true</cobol-count-in>
      <xml-name>catalog-num</xml-name>
      <xml-type>string</xml-type>
      <xml-attribute>false</xml-attribute>
      <xml-namespace></xml-namespace>
   </xml-cobol-mapping>
   <xml-cobol-mapping>
      <cobol-name>product-info.sku-ref</cobol-name>
      <cobol-count-in>true</cobol-count-in>
      <xml-name>sku-ref</xml-name>
      <xml-type>string</xml-type>
      <xml-attribute>false</xml-attribute>
      <xml-namespace></xml-namespace>
   </xml-cobol-mapping>
</xml-cobol-mapping-file>

The map file is an XML document. The tags generated by cbl2xml contain specific information about the COBOL record as follows:

Map file tag name Meaning
<xml-cobol-mapping-file> Indicates that this is a mapping file to be used to create XML structure in a COBOL program. It is the root element of the map file.
<xml-cobol-mapping> Contains information for one COBOL data item. It is the parent element to <cobol-name>, <xml-name>, <xml-type>, <xml-attribute>, and <xml-namespace>.
<cobol-name> Contains the name of a data item from a COBOL record, including the parent name of the data item. The parent name comes first, followed by the data item name, separated by a period (.). For example: a-file-record.a-file-item.
<cobol-count-in> Specifies whether or not the COBOL XML COUNT IN clause is generated for the COBOL item in <cobol-name>. Acceptable values are “true” and “false”. The default value is “true.” This value is ignored when the –nocountin command-line option is used.
<xml-name> Specifies an equivalent XML element name to be used to correspond to the record named in <cobol-name>.
<xml-type> The XML simple type that the COBOL item is being mapped to. This parameter is applicable only when a COBOL data item has a PIC clause.
<xml-attribute> Specifies whether or not the element specified in <xml-name> is to be treated as an attribute in the XML schema. Values are “true” or “false.”
<xml-namespace> An optional element that specifies the XML namespace for the element specified in <xml-name>. A namespace specified at a group level is inherited automatically by child elements.

You can then create user-defined mappings by editing the map file and matching the XML element names found in the schema to the COBOL names found in your COBOL record. To do this, change the <xml-name>s in the map file to match the element names in the schema. In this example, you would edit the <xml-name>s in the map file shown in Example 0-6 as follows:

Change... To...
<xml-name>product-info</xml-name> <xml-name>Widgets</xml-name>
<xml-name>prod-id</xml-name> <xml-name>Product_Id</xml-name>
<xml-name>company-id</xml-name> <xml-name>Company_Id</xml-name>
<xml-name>catalog-num</xml-name> <xml-name>Catalogue_Id</xml-name>
<xml-name>sku-ref</xml-name> <xml-name>SKU</xml-name>

At this point, run cbl2xml again, specifying the edited map file, and cbl2xml produces a schema and a copyfile. The schema will be similar to your existing schema, depending on how much of that existing schema you edited into your map file. You do not need to use this schema; it is created by default and is not critical. The copyfile contains your original COBOL record with the appropriate XML syntax extensions appended to it, based on the information found in the map file. In this example, cbl2xml generates the following copyfile:

        01 product-info identified by "Widgets" 
           count in widgets-count.
         02 prod-id pic 9(6) identified by "Product_Id" 
            count in Product_Id-count.
         02 company-id pic 9(4) identified by "Company_Id" 
            count in Company_Id-count.
         02 catalog-num pic 9(8) identified by "Catalogue_Id" 
            count in Catalogue_Id-count.
         02 sku-ref pic X(10) identified by "SKU" 
            count in SKU-count.

Paste this new record into your COBOL program, replacing the original record. Your COBOL record is now XML-enabled to communicate with XML documents that conform to the widgets.xsd schema.

Accessing an XML-enabled Record

Once you have an XML-enabled record, you'll need to access it from the Procedure Division of your program. You can use existing COBOL verbs to do this and the XML-enhanced syntax for these verbs. See the chapter XML Syntax Extensions for more information.

The following is a sample program with a Procedure Division that writes the contents of the widgets.xml file:

Example 7: Sample COBOL program using XML

        $set p(prexml) endp
        select xml-stream assign "widgets.xml"
                          organization is xml
                          document-type is "widgets.xsd"
                          file status is file-status-spec.

        xd xml-stream.
	       copy "widgets.cpy".

        data division.
        working-storage section.
        01 file-status-spec PIC S9(9).

        procedure division.
          open output xml-stream
          write widgets
          display file-status-spec
          close xml-stream
        stop run.

Validate an XML Document

You can use cbl2xml to validate an XML schema (.xsd file) or instance document (.xml file) to determine if it is well formed. In the case of an instance document, cbl2xml checks the contents of the document against the schema referenced by the document. Use the following syntax:

cbl2xml -v filename

where filename is a schema file or an XML instance document file.