This describes the XML syntax extensions provided to enable COBOL programs to input and output XML.
Yopur COBOL development system supports the creation of relationships between COBOL data structures and element definitions in XML schemas. You can create COBOL XML syntax extensions, which enable you to code references to XML structures right into your COBOL definitions. These XML structures are used to input and output information in an XML format.
Syntax is provided specially designed to XML-enable COBOL. The following paragraph and clause descriptions are specifically for reading and writing XML from COBOL.
Note: If you want to compile the examples in this section, be sure to place the line numbers starting in column 3.
The SELECT paragraph has been extended to enable you to assign a file name to an XML stream using the ASSIGN clause. The ASSIGN clause determines the routing of the XML stream and declares the schema that the stream conforms to. The actual format of the stream is solely determined by the record definitions contained in the XML Descriptor (XD) paragraph in the File Section.
For every file with an organization of XML, a set of record definitions is required to define the format of the XML stream being manipulated. These record definitions are contained in the XD paragraph in the File Section of the source program.
The following are not supported in the XD paragraph:
XML Syntax - XD File Description
Use this syntax when declaring a COBOL data record to map the record to an XML element (tag) or an XML attribute that is defined in an XML schema or document.
You match up an XML tag with a COBOL data record using IDENTIFIED BY, and match up attributes for the XML tags with the addition of IS ATTRIBUTE. For example:
If you had an XML document that contained the following:
<company_name type="accounting">Webber Lynch</company_name>
a matching COBOL record using the IDENTIFIED BY and IS ATTRIBUTE clauses would be as follows:
05 company identified by "company_name". 10 company-name-value pic X(30). 10 company-type pic x(10) identified by "type" is attribute.
XML Syntax - IDENTIFIED BY Clause
You can work with variable tag and attribute names in your XML-enabled program, as well as known tag names. Using this method, you specify tags and attributes by substituting a COBOL data-name for a tag or an attribute name. On an XML file opened for output, this allows you to write purely dynamic and arbitrarily complex XML documents. On a file opened for input this allows you to read such complex documents. For example, the following program reads any XML stream that has a single root tag, any number of single nested tags and any number of attributes per tag:
Example 1: Using the IDENTIFIED BY and IS ATTRIBUTE clauses
0010 $set preprocess(prexml) o(foo.pp) warn endp 0030 0040 select doc assign address of mybuf 0050 organization is xml 0060 document-type is external doc-type 0070 file status is doc-status. 0080 xd doc. 0090 01 root-tag identified by root-tag-name. 0100 10 root-tag-name pic x(80). 0110 10 root-tag-val pic x(80). 0120 10 root-tag-attr identified by root-tag-attr-name 0130 is attribute. 0140 15 root-tag-attr-name pic x(80). 0150 15 root-tag-attr-val pic x(80). 0160 0170 10 sub-tag identified by sub-tag-name. 0180 15 sub-tag-name pic x(80). 0190 15 sub-tag-val pic x(80). 0200 15 sub-tag-attr identified by sub-tag-attr-name 0210 is attribute. 0220 20 sub-tag-attr-val pic x(80). 0230 20 sub-tag-attr-name pic x(80). 0240 0250 working-storage section. 0260 01 doc-type pic x(80). 0270 01 doc-status pic s9(9) comp. 0280 01 mybuf. 0290 10 pic x(300) value 0300 '<library location="here" ' 0310 & 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ' 0320 & 'xsi:schemaLocation="library.xsd">' 0330 & '<book published="yes" goodreading="ok">' 0340 & 'booktext' 0350 & '</book>' 0360 & 'is a place' 0370 & '</library>'. 0380 0390 procedure division. 0400 open input doc 0410 read doc 0420 display "Document type is: " doc-type 0430 display "Tag name: " root-tag-name 0440 display "Tag value:" root-tag-val 0450 start doc key root-tag-attr 0460 *> 0470 *> Loop through all attributes dumping names 0480 *> 0490 0500 perform until exit 0510 read doc next key root-tag-attr 0520 if doc-status not = 0 0530 exit perform 0540 end-if 0550 display "Attribute name : " root-tag-attr-name 0560 display "Attribute value: " root-tag-attr-val 0570 end-perform 0580 0590 *> Loop through all sub-tags 0600 start doc key sub-tag 0610 perform until exit 0620 read doc 0630 next key sub-tag *> index is 1 is default 0640 if doc-status not = 0 0650 exit perform 0660 end-if 0670 display " Sub tag name: " sub-tag-name 0680 display " Sub tag value:" sub-tag-val 0690 0700 start doc key sub-tag-attr index is 1 0710 perform until exit 0720 read doc next key sub-tag-attr 0730 if doc-status not = 0 0740 exit perform 0750 end-if 0760 display " Sub tag attribute name : " 0770 sub-tag-attr-name 0780 display " Sub tag attribute value: " 0790 sub-tag-attr-val 0800 end-perform 0810 end-perform 0820 0830 close doc 0840 0850 stop run.
Lines 0040 - 0070:
0040 select doc assign address of mybuf 0050 organization is xml 0060 document-type is external doc-type 0070 file status is doc-status.
Assigns a filename and the buffer mybuf as the source of the XML input, specifies the organization of the file (XML), provides a data-name that variably specifies the XML schema name, and provides a data-name for the file status.
Lines 0080 - 0230:
0080 xd doc. 0090 01 root-tag identified by root-tag-name. 0100 10 root-tag-name pic x(80). 0110 10 root-tag-val pic x(80). 0120 10 root-tag-attr identified by root-tag-attr-name 0130 is attribute. 0140 15 root-tag-attr-name pic x(80). 0150 15 root-tag-attr-val pic x(80). 0160 0170 10 sub-tag identified by sub-tag-name. 0180 15 sub-tag-name pic x(80). 0190 15 sub-tag-val pic x(80). 0200 15 sub-tag-attr identified by sub-tag-attr-name 0210 is attribute. 0220 20 sub-tag-attr-val pic x(80). 0230 20 sub-tag-attr-name pic x(80).
Sets up the record structure of the buffer area.
Lines 0280 - 0370:
0280 01 mybuf. 0290 10 pic x(300) value 0300 '<library location="here" ' 0310 & 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ' 0320 & 'xsi:schemaLocation="library.xsd">' 0330 & '<book published="yes" goodreading="ok">' 0340 & 'booktext' 0350 & '</book>' 0360 & 'is a place' 0370 & '</library>'.
Codes the XML stream to be read into a static buffer. While this example has the XML stream coded directly into the program, you could also place the XML into the buffer (mybuf) using any standard input.
Lines 0400 - 0440:
0400 open input doc 0410 read doc 0420 display "Document type is: " doc-type 0430 display "Tag name: " root-tag-name 0440 display "Tag value:" root-tag-val
Opens the buffer area, reads in the XML record, and displays the document type, the name of the root tag, and the value of the root tag.
Line 0450:
0450 start doc key root-tag-attr
Sets the starting point in the buffer to the first attribute for the root tag.
Lines 0500 - 0570:
0500 perform until exit 0510 read doc next key root-tag-attr 0520 if doc-status not = 0 0530 exit perform 0540 end-if 0550 display "Attribute name : " root-tag-attr-name 0560 display "Attribute value: " root-tag-attr-val 0570 end-perform
Loops through information in the root tag, reading each attribute for the root tag and displaying the attribute names and values.
Line 0600:
0600 start doc key sub-tag
Sets the starting point in the buffer to the first nested tag (non-root tag).
Lines 0610 - 0810
0610 perform until exit 0620 read doc 0630 next key sub-tag *> index is 1 is default 0640 if doc-status not = 0 0650 exit perform 0660 end-if 0670 display " Sub tag name: " sub-tag-name 0680 display " Sub tag value:" sub-tag-val 0690 0700 start doc key sub-tag-attr index is 1 0710 perform until exit 0720 read doc next key sub-tag-attr 0730 if doc-status not = 0 0740 exit perform 0750 end-if 0760 display " Sub tag attribute name : " 0770 sub-tag-attr-name 0780 display " Sub tag attribute value: " 0790 sub-tag-attr-val 0800 end-perform 0810 end-perform
Loops through all non-root tags, displaying each XML tag name and value, and all its attribute names and values.
The PROCESSING-INSTRUCTION clause is provided simply to allow XML processing instructions to be embedded directly within the data associated with a tag. For example, the following code:
01 my-tag identified by "my_tag". 05 my-tag-data1 pic x(80). 05 my-tag-pi pic x(80) IS PROCESSING-INSTRUCTION. 05 my-tag-data2 pic x(80). ... move 'data' to my-tag-data1 my-tag-data2 move 'somepi' to my-tag-pi write my-tag
Would yield:
<my_tag>data<?somepi?>data</my_tag>
XML Syntax - PROCESSING-INSTRUCTION Clause
As shown in the section IDENTIFIED BY and IS ATTRIBUTE Clauses, it is possible to deal with unlimited multiple occurrences of known or unknown tag names through the use of various XML-extended verbs. In less complicated cases where the number of occurrences is known in advance, there are very simple syntax extensions that allow direct addressing.
You can deal with a known number of tag or attribute occurrences using the OCCURS and COUNT IN clauses. The number of acceptable occurrences of a tag or attribute is limited by the OCCURS clause. The COUNT IN clause enables you to determine the number of occurrences received or to specify the number to be sent.
The following example shows how to use the COUNT IN clause:
Example 2: Using OCCURS and COUNT IN clauses
0010 $set preprocess(prexml) warn endp 0020 $set sourceformat(free) case 0030 0040 select library-file 0050 assign address of mybuf 0060 organization is xml 0070 document-type is "library.xsd" 0080 file status is library-status. 0090 0100 data division. 0110 0120 xd library-file. 0130 01 library identified by "library". 0140 05 book identified by "book" 0150 occurs 10 times 0160 count in library-book-count. 0170 10 book-title pic x(80) identified by "title". 0180 10 book-author pic x(80) identified by "author". 0190 10 book-toc identified by "toc". 0200 15 book-toc-section occurs 20 times 0210 count in book-section-count 0220 identified by "section" 0230 pic x(20). 0240 0250 working-storage section. 0260 01 library-status pic s999. 0270 01 mybuf. 0280 10 pic x(150) value 0290 '<library>' 0300 & '<book><title>book1</title>' 0310 &' <toc><section>b1section1</section>' 0320 & ' <section>b1section2</section>' 0330 & '</toc></book>'. 0340 10 pic x(150) value 0350 '<book><title>book2</title>' 0360 & ' <toc><section>b2section1</section>' 0370 & ' <section>b2section2</section>' 0380 & '</toc></book>' 0390 & '</library>'. 0400 0410 open input library-file 0420 read library-file 0430 perform until library-book-count = 0 0440 display 0450 "Book title = '" book-title(library-book-count) "'" 0460 display "Number of Sects = " 0470 book-section-count(library-book-count) 0480 subtract 1 from library-book-count 0490 end-perform 0500 close library-file 0510 stop run.
Lines 0040 - 0080:
0040 select library-file 0050 assign address of mybuf 0060 organization is xml 0070 document-type is "library.xsd" 0080 file status is library-status.
Assigns a filename and the buffer mybuf as the source of the XML input, specifies the organization of the file (XML) and provides a filename for the XML schema (library.xsd) and a data-name for the file status.
Lines 0120 - 0230:
0120 xd library-file. 0130 01 library identified by "library". 0140 05 book identified by "book" 0150 occurs 10 times 0160 count in library-book-count. 0170 10 book-title pic x(80) identified by "title". 0180 10 book-author pic x(80) identified by "author". 0190 10 book-toc identified by "toc". 0200 15 book-toc-section occurs 20 times 0210 count in book-section-count 0220 identified by "section" 0230 pic x(20).
Sets up the record structure of the buffer area. Notice the use of OCCURS and COUNT-IN. In this example, the book data-name is identified by the XML tag <book>, it occurs 10 times, and the occurrences are counted in the library-book-count field, which is defined implicitly. The book-toc-section data item is defined similarly, with book-section-count defined implicitly.
Lines 0270 - 0390:
0270 01 mybuf. 0280 10 pic x(150) value 0290 '<library>' 0300 & '<book><title>book1</title>' 0310 &' <toc><section>b1section1</section>' 0320 & ' <section>b1section2</section>' 0330 & '</toc></book>'. 0340 10 pic x(150) value 0350 '<book><title>book2</title>' 0360 & ' <toc><section>b2section1</section>' 0370 & ' <section>b2section2</section>' 0380 & '</toc></book>' 0390 & '</library>'.
Codes the XML stream to be read in a static buffer. While this example has the XML stream coded directly into the program, you could also place the XML into the buffer (mybuf) using any standard input.
Lines 0430 - 0490:
0430 perform until library-book-count = 0 0440 display 0450 "Book title = '" book-title(library-book-count) "'" 0460 display "Number of Sects = " 0470 book-section-count(library-book-count) 0480 subtract 1 from library-book-count 0490 end-perform
Loops through all records, displaying all book titles and the number of sections contained in each. Notice that book-section-count uses library-book-count as an index.
The COUNT IN clause is also very useful to determine if the tag associated with an element definition was present in the XML stream. A very common use of this is determining which of a set of XD records is read during the execution of a READ statement. For example:
Example 3: Using COUNT IN to determine which record has been read
0010 select book-or-author-file 0020 assign address of mybuf 0030 organization is xml 0040 document-type is "bookdb.xsd" 0050 file status is xml-bookdb-status. 0060 0070 data division. 0080 xd book-or-author-file. 0090 01 book-rec identified by "book" 0100 count in book-count. 0110 05 price-val pic 999.99 identified by "price" 0120 is attribute 0130 count in price-count. 0140 05 title-val pic x(80) identified by "title". 0150 0160 01 author-rec identified by "author" 0170 count in author-count. 0180 05 author-val pic x(80). 0190 0200 working-storage section. 0210 01 xml-bookdb-status pic s999. 0220 01 mybuf pic x(256) value 0230 '<book price="123.00"><title>A title</title></book>'. 0240 0250 procedure division. 0260 open input book-or-author-file 0270 read book-or-author-file 0280 evaluate true 0290 when book-count = 1 0300 if price-count not = 0 0310 display "got <book price=" price-val "> 0320 <title>" title-val "</title></book>" 0330 else 0340 display "got <book><title>" title-val 0350 "</title></book>" 0360 end-if 0370 when author-count = 1 0380 display "got <author>" author-val "</author>" 0390 end-evaluate 0400 close book-or-author-file 0410 stop run.
Lines 0010 - 0050:
0010 select book-or-author-file 0020 assign address of mybuf 0030 organization is xml 0040 document-type is "bookdb.xsd" 0050 file status is xml-bookdb-status.
Assigns a filename and the buffer mybuf as the source of the XML input, specifies the organization of the file (XML) and provides a filename for the XML schema (bookdb.xsd) and a data-name for the file status.
Lines 0080 - 0180:
0080 xd book-or-author-file. 0090 01 book-rec identified by "book" 0100 count in book-count. 0110 05 price-val pic 999.99 identified by "price" 0120 is attribute 0130 count in price-count. 0140 05 title-val pic x(80) identified by "title". 0150 0160 01 author-rec identified by "author" 0170 count in author-count. 0180 05 author-val pic x(80).
Defines two 01 level items, one for a book record, and one for an author record. Later, the program uses the information defined by COUNT IN to determine which record is being read.
Lines 0220 - 0230:
0220 01 mybuf pic x(256) value 0230 '<book price="123.00"><title>A title</title></book>'.
Codes the XML stream to be read in a static buffer. While this example has the XML stream coded directly into the program, you could also place the XML into the buffer (mybuf) using any standard input.
Lines 0260 - 0390:
0260 open input book-or-author-file 0270 read book-or-author-file 0280 evaluate true 0290 when book-count = 1 0300 if price-count not = 0 0310 display "got <book price=" price-val "> 0320 <title>" title-val "</title></book>" 0330 else 0340 display "got <book><title>" title-val 0350 "</title></book>" 0360 end-if 0370 when author-count = 1 0380 display "got <author>" author-val "</author>" 0390 end-evaluate
The EVALUATE clause determines which record is being read based on the value of book-count or author-count.
XML documents often contain namespaces. The NAMESPACE clause enables you to set or identify those namespaces in your COBOL. Specify the NAMESPACE clause in a data description entry. The following example shows how to use the NAMESPACE clause:
Example 4: Using NAMESPACE
0010 xd book-file. 0020 78 book-ns value "http://xml.microfocus.com/book.xsd". 0030 01 book identified by "book" 0040 namespace is book-ns. 0050 05 publisher pic x(80) 0060 identified by "name" 0070 namespace is 0080 "http://xml.microfocus.com/publisher.xsd". 0090 0100 05 author identified by "name" 0110 namespace is 0120 "http://xml.microfocus.com/author.xsd". 0130 10 author-first identified by "firstname" 0140 pic x(80). 0150 10 author-last identified by "lastname" 0160 pic x(80). 0170 05 title identified by "title" 0180 pic x(80).
Line 0020:
0020 78 book-ns value "http://xml.microfocus.com/book.xsd".
Defines a namespace and its value.
Lines 0030 - 0040:
0030 01 book identified by "book" 0040 namespace is book-ns.
Defines a data record with a namespace equivalent to the value in book-ns.
Lines 0050 - 0080:
0050 05 publisher pic x(80) 0060 identified by "name" 0070 namespace is 0080 "http://xml.microfocus.com/publisher.xsd".
Sets a namespace to a fixed URI (Uniform Resource Identifier), which is a specific point of contact on the World Wide Web - in this case an XML schema file.
Lines 0100 - 0120:
0100 05 author identified by "name" 0110 namespace is 0120 "http://xml.microfocus.com/author.xsd".
Sets a namespace to a fixed URI.
Lines 0130 - 0160:
0130 10 author-first identified by "firstname" 0140 pic x(80). 0150 10 author-last identified by "lastname" 0160 pic x(80).
Because these data items are in the author group, they take on the same namespace as author.
Lines 0170 - 0180:
0170 05 title identified by "title" 0180 pic x(80).
Title inherits the same namespace as book because it is in the book group but does not specify a namespace.
On input, both tags and namespaces must match those in the XML stream. On output, XML tags are qualified by the indicated namespace. The code in Example 0-4 would yield an XML stream similar to:
<?xml version="1.0" encoding="utf-8" ?> <book xmlns="http://xml.microfocus.com/book.xsd"> <name xmlns="http://xml.microfocus.com/publisher.xsd"> Just a publisher </name> <name xmlns="http://xml.microfocus.com/author.xsd"> <firstname>AuthorFirstname</firstname> <lastname>AuthorFirstname</lastname> </name> <title> This is the title </title> </book>
You can replace a specific NAMESPACE value with a data-name. This facilitates dynamic discovery of a namespace in XML. In this case, namespace matching is not performed on input. Instead, the namespace of the matching tag is populated into the data item specified by NAMESPACE. On output, the value of the namespace referenced by the data-name is used to qualify the output tag. The following record:
xd generic-file. 01 generic-tag identified by generic-tag-name namespace is generic-tag-namespace. 05 generic-tag-name pic x(80). 05 generic-tag-namespace pic x(80). 05 generic-tag-value pic x(80).
and XML stream input:
<name xmlns="http://xml.microfocus.com/publisher.xsd"> Just a publisher </name>
yields the value of "name" for generic-tag-name, the value of "http://xml.microfocus.com/publisher.xsd" for generic-tag-namespace and the value of "Just a publisher" for generic-tag-value.
Some familiar COBOL verbs have also been extended to handle XML. They are:
You can directly use XML syntax extensions to create a client for an XML-enabled CGI-based application by using the ASSIGN "http://...." syntax in your client. The following is an example of program that creates a client for a CGI-based program, calccgi, running on the local host:
Example 5: Client-side application with XML syntax extensions
0010 $set preprocess(prexml) o(calc.pp) endp 0020 0030 program-id. "calc". 0040 select xml-calc 0050 assign "http://localhost/cgibin/calccgi.exe" 0060 organization is xml 0070 document-type is "calc.xsd" 0080 file status is xml-calc-status. 0090 0100 data division. 0110 xd xml-calc. 0120 01 xml-record identified by "request" 0130 count in xml-record-check. 0140 05 xml-num-1 pic 99 identified by "num1". 0150 05 xml-num-2 pic 99 identified by "num2". 0160 05 xml-func pic x(3) identified by "func". 0170 05 xml-result pic ----9 identified by "result". 0180 0190 working-storage section. 0200 01 xml-calc-status pic s9(9) comp-5. 0210 0220 procedure division. 0230 0240 open i-o xml-calc 0250 if xml-calc-status not = 0 0260 display "Error opening channel" 0270 stop run 0280 end-if 0290 0300 move "subtract" to xml-func 0310 move 2 to xml-num-1 0320 move 3 to xml-num-2 0330 perform doit 0340 0350 move "add" to xml-func 0360 perform doit 0370 0380 close xml-calc 0390 stop run. 0400 0410 doit section. 0420 0430 write xml-record 0440 display "Function call :" xml-func 0450 if xml-calc-status < 0 0460 exhibit named xml-calc-status 0470 stop run 0480 end-if 0490 0500 read xml-calc 0510 0520 if xml-calc-status < 0 0530 exhibit named xml-calc-status 0540 stop run 0550 end-if 0560 0570 if xml-record-check > 0 *> Output 0580 exhibit named xml-num-1 0590 exhibit named xml-num-2 0600 exhibit named xml-func 0610 exhibit named xml-result 0620 end-if.
Line 0040 - 0080:
0040 select xml-calc 0050 assign "http://localhost/cgibin/calccgi.exe" 0060 organization is xml 0070 document-type is "calc.xsd" 0080 file status is xml-calc-status.
Assigns a CGI application to xml-calc.
This next example is of a matching server-side program that services this client. Notice the use of the ":CGI:" filename. The ":CGI:" assignment instructs the run-time system to respect the CGI standard CONTENT_LENGTH environment variable.
Example 6: Server-side CGI application with XML syntax extensions
0010 $set preprocess(prexml) o(calccgi.pp) endp 0020 0030 program-id. "calccgi". 0040 0050 select xml-calc assign ":CGI:" 0060 organization is xml 0070 document-type is "calc.xsd" 0080 file status is xml-calc-status. 0090 0100 data division. 0110 xd xml-calc. 0120 01 xml-record identified by "request" 0130 count in xml-record-check. 0140 05 xml-num-1 pic 99 identified by "num1". 0150 05 xml-num-2 pic 99 identified by "num2". 0160 05 xml-func pic x(3) identified by "func". 0170 05 xml-result pic ----9 identified by "result". 0180 0190 working-storage section. 0200 01 xml-calc-status pic s9(9) comp-5. 0210 0220 procedure division. 0230 0240 open input xml-calc 0250 if xml-calc-status not = 0 0260 display "Error opening input channel" 0270 stop run 0280 end-if 0290 0300 read xml-calc 0310 0320 if xml-calc-status < 0 0330 exhibit named xml-calc-status 0340 display "Error reading channel " 0350 stop run 0360 end-if 0370 0380 if xml-record-check > 0 *> Input was correct 0390 close xml-calc 0400 0410 open output xml-calc 0420 if xml-calc-status not = 0 0430 display "Error opening output channel" 0440 stop run 0450 end-if 0460 0470 evaluate true 0480 when xml-func = "add" 0490 add xml-num-2 to xml-num-1 0500 giving xml-result 0510 when xml-func = "sub" 0520 subtract xml-num-2 from xml-num-1 0530 giving xml-result 0540 when xml-func = "mul" 0550 multiply xml-num-1 by xml-num-2 0560 giving xml-result 0570 when xml-func = "div" 0580 divide xml-num-1 by xml-num-2 0590 giving xml-result 0600 end-evaluate 0610 0620 write xml-record key is plain-text 0630 "Content-type: text/xml" & x"0d0a" 0640 write xml-record 0650 end-if 0660 close xml-calc. 0670 stop run.
Line 0050 - 0080:
0050 select xml-calc assign ":CGI:" 0060 organization is xml 0070 document-type is "calc.xsd" 0080 file status is xml-calc-status.
Using the ":CGI:" filename is critical, as input to a CGI program is undefined if there is an attempt to read more data than specified in the CGI CONTENT_LENGTH value. The ":CGI:" assignment instructs the run-time system to respect this variable.
Line 0380:
0380 if xml-record-check > 0 *> Input was correct
xml-record-check holds the number of data items in the stream. If it is greater than zero, then the execution of the READ statement did find data.
Lines 0390 - 0410:
0390 close xml-calc 0400 0410 open output xml-calc
This closes the XML input stream and reopens it as an output stream. A CGI application typically opens ":CGI:" in input mode to read the XML data, closes that input stream, and then opens ":CGI:" in output mode to produce output.
Line 0620:
0620 write xml-record key is plain-text
Under some Web servers the PLAIN-TEXT value "Content-type: text/xml" is a required prefix to any CGI output.
To compile or build COBOL that has been XML-enabled using XML syntax extensions, the code must be preprocessed by the XML preprocessor in your COBOL development system. This is a necessary step that enables the Compiler to recognize the XML syntax you've coded into your program.
You compile or build XML-enabled COBOL in one of two ways:
Before you build your XML-enabled COBOL from the IDE, you must insert the following code on the first line of your program before the Identification Division:
$set {preprocess | p}(prexml) [{out | o} (outname)] [warn] [{preprocess | p} (ppname)] endp
where the parameters are:
{preprocess | p} | The pre-processor to be used. |
{out | o} outname | The fully preprocessed output source file, outname. This output source file contains native COBOL processed from the XML syntax. |
warn | Cause diagnostic warnings on parsing to be presented by PREXML. |
ppname | The preprocessor name you want to use to read source files and process COPY statements. Preprocessors can be nested. |
For example:
$set p(prexml) warn endp
If you have the $set statement coded into your program, then you compile from the command line just as you would a program that is not XML enabled. However, if you do not have the $set statement coded into your program, or you would like to override all of the parameters specified in your $set statement, specify a command line as follows:
cob programname.cbl -C "{preprocess | p}(prexml) [{out | o} (outname)] [warn] [{preprocess | p} (ppname)] endp"
where programname is the file prefix of the COBOL program you are compiling, and the other parameters are the same as those used with the $set statement. See the section Building from Server Express above for an explanation of these parameters.
For example:
cob foo.cbl -C "p(prexml) warn endp"