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
When used in nested programs, these special registers are implicitly defined as GLOBAL in the outermost program.
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
, connect the multiple charts in this chapter. In particular,
in the following figure connects to the chart Control flow
for XML exceptions, and
connects from XML CCSID exception flow control.
Control flow between XML parser and program, showing XML-CODE usage
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.
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:
Note, however, that use of these functions is at the expense of performance.
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.
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.
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)
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's best"/>'. 2 pic x(41) value ' <?spread please use real mayonnaise ?>'. 2 pic x(31) value ' <meat>Ham & 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.
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's best"/> <?spread please use real mayonnaise ?> <meat>Ham & 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>
(C) Copyright IBM Corporation 1992, 2005. All Rights Reserved.