ILE COBOL Programmer's Guide

Writing procedures to process XML

In your processing procedure, code the statements to handle XML events.

For each event that the parser encounters, it passes information to your processing procedure in several special registers, as shown in the following table. Use these registers to populate your data structures and to control your processing.


Table 15. Special registers used by the XML parser

Special register Contents Implicit definition and usage
XML-EVENT1
The name of the XML event PICTURE X(30) USAGE DISPLAY
VALUE SPACE
XML-CODE
An exception code or zero for each XML event PICTURE S9(9) USAGE BINARY
VALUE ZERO
XML-TEXT1
Text (corresponding to the event that the parser encountered) from the XML document if you specify an alphanumeric data item for the XML PARSE identifier Variable-length alphanumeric data item; 16,000,000 byte size limit
XML-NTEXT1
Text (corresponding to the event that the parser encountered) from the XML document if you specify a national data item for the XML PARSE identifier Variable-length national data item; 16,000,000 byte size limit
  1. You cannot use this special register as a receiving data item.

When used in nested programs, these special registers are implicitly defined as GLOBAL in the outermost program.

Understanding the contents of XML-CODE

When the parser returns control to your XML PARSE statement, XML-CODE contains the most recent value set by the parser or your processing procedure.

For all events except the EXCEPTION event, the value of the XML-CODE special register is zero. If you set the XML-CODE special register to -1 before you return control to the XML parser for an event other than EXCEPTION, processing stops with a user-initiated exception indicated by the returned XML-CODE value of -1. The result of changing the XML-CODE to any other nonzero value before returning from any event is undefined.

For the EXCEPTION event, special register XML-CODE contains the exception code.

The following figure shows the flow of control between the parser and your processing procedure and how XML-CODE is used to pass information between the two. The off-page connectors, such as Begin image description. Off-page flow-chart connector. End image description., connect the multiple charts in this chapter. In particular, Begin image description. E off-page connector. End image description. in the following figure connects to the chart Control flow for XML exceptions, and Begin image description. P off-page connector. End image description. connects from XML CCSID exception flow control.

Control flow between XML parser and program, showing XML-CODE usage


Begin image description. Flow chart of control flow between XML parser and program with XML-CODE usage, which is described in surrounding text. End image description.

Using XML-TEXT and XML-NTEXT

The special registers XML-TEXT and XML-NTEXT are mutually exclusive. The type of XML identifier that you specify determines which special register is set, except for the ATTRIBUTE-NATIONAL-CHARACTER and CONTENT-NATIONAL-CHARACTER events. For these events, XML-NTEXT is set regardless of the data item that you specify for the XML PARSE identifier.

When the parser sets XML-TEXT, XML-NTEXT is undefined (length of 0). When the parser sets XML-NTEXT, XML-TEXT is undefined (length of 0).

To determine how many national characters XML-NTEXT contains, use the LENGTH function. LENGTH OF XML-NTEXT contains the number of bytes, rather than characters, used by XML-NTEXT.

Transforming XML text to COBOL data items

Because XML data is neither fixed length nor fixed format, you need to use special techniques when you move the XML data to COBOL data items.

For alphanumeric items, decide whether the XML data should go at the left (default) end of your COBOL item, or at the right end. If it should go at the right end, specify the JUSTIFIED RIGHT clause in the declaration of the COBOL item.

Give special consideration to numeric XML values, particularly "decorated" monetary values such as '$1,234.00' and '$1234'. These mean the same thing in XML but have completely different declarations as COBOL sending fields. Use this technique:

Restriction on your processing procedure

Your processing procedure must not directly execute an XML PARSE statement. However, if your processing procedure passes control to an outermost program using a CALL statement, the target method or program can execute the same or a different XML PARSE statement. You can also execute the same XML statement or different XML statements simultaneously from a program that is executing on multiple threads.

Ending your processing procedure

The compiler inserts a return mechanism after the last statement in your processing procedure. You can code a STOP RUN statement in your processing procedure to terminate the run unit. However, the GOBACK or EXIT PROGRAM statements do not return control to the parser. Using either statement in your processing procedure results in a severe error.

Examples: parsing XML

related references
XML exceptions that allow continuation
XML exceptions that do not allow continuation
XML-CODE (ILE COBOL Language Reference)
XML-EVENT (ILE COBOL Language Reference)
XML-NTEXT (ILE COBOL Language Reference)
XML-TEXT (ILE COBOL Language Reference)

Examples: parsing XML

This example shows the basic organization of an XML PARSE statement and a processing procedure, where the XML document is in a COBOL data item. The XML document is given in the source so that you can follow the flow of the parse. The output of the program is given below. Compare the document to the output of the program to follow the interaction of the parser and the processing procedure and to match events to document fragments.

Example: parsing XML from a data item

 Process APOST
 Identification division.
   Program-id. xmlsampl1.
 
 Data division.
  Working-storage section.
******************************************************************
* XML document, encoded as initial values of data items.         *
******************************************************************
   1 xml-document.
    2 pic x(39) value '<?xml version="1.0" encoding="ibm-37"'.
    2 pic x(19) value ' standalone="yes"?>'.
    2 pic x(39) value '<!--This document is just an example-->'.
    2 pic x(10) value '<sandwich>'.
    2 pic x(35) value '  <bread type="baker&apos;s best"/>'.
    2 pic x(41) value '  <?spread please use real mayonnaise  ?>'.
    2 pic x(31) value '  <meat>Ham &amp; turkey</meat>'.
    2 pic x(40) value '  <filling>Cheese, lettuce, tomato, etc.'.
    2 pic x(10) value '</filling>'.
    2 pic x(35) value '  <![CDATA[We should add a <relish>'.
    2 pic x(22) value ' element in future!]]>'.
    2 pic x(31) value '  <listprice>$4.99 </listprice>'.
    2 pic x(27) value '  <discount>0.10</discount>'.
    2 pic x(11) value '</sandwich>'.
   1 xml-document-length computational pic 999.
 
******************************************************************
* Sample data definitions for processing numeric XML content.    *
******************************************************************
   1 current-element pic x(30).
   1 list-price computational pic 9v99 value 0.
   1 discount computational pic 9v99 value 0.
   1 display-price pic $$9.99.
 
 Procedure division.
  mainline section.
 
     XML PARSE xml-document PROCESSING PROCEDURE xml-handler
       ON EXCEPTION
         display 'XML document error ' XML-CODE
       NOT ON EXCEPTION
         display 'XML document successfully parsed'
     END-XML
 
******************************************************************
*    Process the transformed content and calculate promo price.  *
******************************************************************
     display ' '
     display '-----+++++***** Using information from XML '
         '*****+++++-----'
     display ' '
     move list-price to display-price
     display '  Sandwich list price: ' display-price
     compute display-price = list-price * (1 - discount)
     display '  Promotional price:   ' display-price
     display '  Get one today!'
 
     goback.
 
  xml-handler section.
     evaluate XML-EVENT
* ==> Order XML events most frequent first
       when 'START-OF-ELEMENT'
         display 'Start element tag: <' XML-TEXT '>'
         move XML-TEXT to current-element
       when 'CONTENT-CHARACTERS'
         display 'Content characters: <' XML-TEXT '>'
* ==> Transform XML content to operational COBOL data item...
         evaluate current-element
           when 'listprice'
* ==> Using function NUMVAL-C...
             compute list-price = function numval-c(XML-TEXT)
           when 'discount'
             compute discount = function numval-c(XML-TEXT)
         end-evaluate
       when 'END-OF-ELEMENT'
         display 'End element tag: <' XML-TEXT '>'
         move spaces to current-element
       when 'START-OF-DOCUMENT'
         compute xml-document-length = function length(XML-TEXT)
         display 'Start of document: length=' xml-document-length
             ' characters.'
       when 'END-OF-DOCUMENT'
         display 'End of document.'
       when 'VERSION-INFORMATION'
         display 'Version: <' XML-TEXT '>'
       when 'ENCODING-DECLARATION'
         display 'Encoding: <' XML-TEXT '>'
       when 'STANDALONE-DECLARATION'
         display 'Standalone: <' XML-TEXT '>'
       when 'ATTRIBUTE-NAME'
         display 'Attribute name: <' XML-TEXT '>'
       when 'ATTRIBUTE-CHARACTERS'
         display 'Attribute value characters: <' XML-TEXT '>'
       when 'ATTRIBUTE-CHARACTER'
         display 'Attribute value character: <' XML-TEXT '>'
       when 'START-OF-CDATA-SECTION'
         display 'Start of CData: <' XML-TEXT '>'
       when 'END-OF-CDATA-SECTION'
         display 'End of CData: <' XML-TEXT '>'
       when 'CONTENT-CHARACTER'
         display 'Content character: <' XML-TEXT '>'
       when 'PROCESSING-INSTRUCTION-TARGET'
         display 'PI target: <' XML-TEXT '>'
       when 'PROCESSING-INSTRUCTION-DATA'
         display 'PI data: <' XML-TEXT '>'
       when 'COMMENT'
         display 'Comment: <' XML-TEXT '>'
       when 'EXCEPTION'
         compute xml-document-length = function length (XML-TEXT)
         display 'Exception ' XML-CODE ' at offset '
             xml-document-length '.'
       when other
         display 'Unexpected XML event: ' XML-EVENT '.'
     end-evaluate
     .
 End program xmlsampl1.
 

Output from parse example

From the following output you can see which events of the parse came from which fragments of the document:

Start of document: length=390 characters.
Version: <1.0>
Encoding: <ibm-37>
Standalone: <yes>
Comment: <This document is just an example>
Start element tag: <sandwich>
Content characters: <  >
Start element tag: <bread>
Attribute name: <type>
Attribute value characters: <baker>
Attribute value character: <'>
Attribute value characters: <s best>
End element tag: <bread>
Content characters: <  >
PI target: <spread>
PI data: <please use real mayonnaise  >
Content characters: <  >
Start element tag: <meat>
Content characters: <Ham >
Content character: <&>
Content characters: < turkey>
End element tag: <meat>
Content characters: <  >
Start element tag: <filling>
Content characters: <Cheese, lettuce, tomato, etc.>
End element tag: <filling>
Content characters: <  >
Start of CData: <<![CDATA[>
Content characters: <We should add a <relish> element in future!>
End of CData: <]]>>
Content characters: <  >
Start element tag: <listprice>
Content characters: <$4.99 >
End element tag: <listprice>
Content characters: <  >
Start element tag: <discount>
Content characters: <0.10>
End element tag: <discount>
End element tag: <sandwich>
End of document.
XML document successfully parsed
 
-----+++++***** Using information from XML *****+++++-----
 
  Sandwich list price:  $4.99
  Promotional price:    $4.49
  Get one today!

Example: parsing XML from an IFS file

This example shows an XML PARSE statement that parses an XML document located in an IFS file. The output from the program is the same as in the previous example. The IFS file must have a valid CCSID. The end of each line in the IFS file must have only a CR (carriage return) and not a LF (line feed).

 Process APOST
 Identification division.
   Program-id. xmlsampl2.
 
 Data division.
  Working-storage section.
******************************************************************
* XML document, encoded as initial values of data items.         *
******************************************************************
   1 xml-id pic x(27) value '/home/user1/xmlsampldoc.xml'.
   1 xml-document-length computational pic 999.
 
******************************************************************
* Sample data definitions for processing numeric XML content.    *
******************************************************************
   1 current-element pic x(30).
   1 list-price computational pic 9v99 value 0.
   1 discount computational pic 9v99 value 0.
   1 display-price pic $$9.99.
 
 Procedure division.
  mainline section.
 
     XML PARSE FILE-STREAM xml-id PROCESSING PROCEDURE xml-handler
       ON EXCEPTION
         display 'XML document error ' XML-CODE
       NOT ON EXCEPTION
         display 'XML document successfully parsed'
     END-XML
 
******************************************************************
*    Process the transformed content and calculate promo price.  *
******************************************************************
     display ' '
     display '-----+++++***** Using information from XML '
         '*****+++++-----'
     display ' '
     move list-price to display-price
     display '  Sandwich list price: ' display-price
     compute display-price = list-price * (1 - discount)
     display '  Promotional price:   ' display-price
     display '  Get one today!'
 
     goback.
 
  xml-handler section.
     evaluate XML-EVENT
* ==> Order XML events most frequent first
       when 'START-OF-ELEMENT'
         display 'Start element tag: <' XML-TEXT '>'
         move XML-TEXT to current-element
       when 'CONTENT-CHARACTERS'
         display 'Content characters: <' XML-TEXT '>'
* ==> Transform XML content to operational COBOL data item...
         evaluate current-element
           when 'listprice'
* ==> Using function NUMVAL-C...
             compute list-price = function numval-c(XML-TEXT)
           when 'discount'
             compute discount = function numval-c(XML-TEXT)
         end-evaluate
       when 'END-OF-ELEMENT'
         display 'End element tag: <' XML-TEXT '>'
         move spaces to current-element
       when 'START-OF-DOCUMENT'
         compute xml-document-length = function length(XML-TEXT)
         display 'Start of document: length=' xml-document-length
             ' characters.'
       when 'END-OF-DOCUMENT'
         display 'End of document.'
       when 'VERSION-INFORMATION'
         display 'Version: <' XML-TEXT '>'
       when 'ENCODING-DECLARATION'
         display 'Encoding: <' XML-TEXT '>'
       when 'STANDALONE-DECLARATION'
         display 'Standalone: <' XML-TEXT '>'
       when 'ATTRIBUTE-NAME'
         display 'Attribute name: <' XML-TEXT '>'
       when 'ATTRIBUTE-CHARACTERS'
         display 'Attribute value characters: <' XML-TEXT '>'
       when 'ATTRIBUTE-CHARACTER'
         display 'Attribute value character: <' XML-TEXT '>'
       when 'START-OF-CDATA-SECTION'
         display 'Start of CData: <' XML-TEXT '>'
       when 'END-OF-CDATA-SECTION'
         display 'End of CData: <' XML-TEXT '>'
       when 'CONTENT-CHARACTER'
         display 'Content character: <' XML-TEXT '>'
       when 'PROCESSING-INSTRUCTION-TARGET'
         display 'PI target: <' XML-TEXT '>'
       when 'PROCESSING-INSTRUCTION-DATA'
         display 'PI data: <' XML-TEXT '>'
       when 'COMMENT'
         display 'Comment: <' XML-TEXT '>'
       when 'EXCEPTION'
         compute xml-document-length = function length (XML-TEXT)
         display 'Exception ' XML-CODE ' at offset '
             xml-document-length '.'
       when other
         display 'Unexpected XML event: ' XML-EVENT '.'
     end-evaluate
     .
 End program xmlsampl2.
 

Here is the IFS file for this example, from /home/user1/xmlsampldoc.xml.

<?xml version="1.0" encoding="ibm-37"
  standalone="yes"?>
<!--This document is just an example-->
<sandwich>
 <bread type="baker&apos;s best"/>
 <?spread please use real mayonnaise  ?>
 <meat>Ham &amp; turkey</meat>
 <filling>Cheese, lettuce, tomato, etc.
</filling>
 <![CDATA[We should add a <relish> element in future!]]>
 <listprice>$4.99 </listprice>
 <discount>0.10</discount>
</sandwich>


[ Top of Page | Previous Page | Next Page | Table of Contents | Index ]