Example: Using unbounded tables for parsing XML documents

Consider using unbounded tables when parsing an XML document with an unknown number of repetitive elements.

You can use any of the following methods:
  • Predetermine the number of elements to expect. One method to determine the number of elements is to parse the XML document twice. During the first parse, count the number of occurrences of each unbounded element in the corresponding OCCURS UNBOUNDED DEPENDING ON object. Then, allocate storage for the data items using these computed values, and parse the XML document a second time to process its payload.
  • Pick initial sizes and allow for expansion of the tables. It might be more efficient to set arbitrary limits in the OCCURS UNBOUNDED DEPENDING ON objects based on previous experience, and parse the document directly to process its content. For each unbounded element, check if the current limit is about to be exceeded. If so, allocate more storage for the corresponding array, copy the data from the old array to the expanded array, then free the storage for the old array.

The following examples illustrate the first method. See the XML schema example, and note that elements B and C have a maxOccurs value of unbounded, and thus can occur an unlimited number of times in the sequence within element G. In the XML document example, element B in fact occurs three times, and element C occurs five times.

In the XML processing program example, the processing procedure for the first XML PARSE statement simply computes the number of occurrences of elements B and C. After allocating the required storage, the program executes a second XML PARSE statement to process the XML payload.

XML schema

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema targetNamespace="http://example.org"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="G">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="A" type="xsd:string" maxOccurs="1" />
<xsd:element name="B" type="xsd:int" maxOccurs="unbounded" />
<xsd:element name="C" type="xsd:int" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>

XML document

<?xml version="1.0" encoding="UTF-8"?>
<p:G xmlns:p="http://example.org" >
<A>Hello</A>
<B>1</B>
<B>2</B>
<B>3</B>
<C>1</C>
<C>2</C>
<C>3</C>
<C>4</C>
<C>5</C>
</p:G>

XML processing program

Identification division.
Program-id. XMLProc.
Data division.
Working-storage section.
01 NB pic S9(9) binary value zero.
01 NC pic S9(9) binary value zero.
01 Gptr pointer.
01 Gsize pic 9(9) binary.
01 Heap0 pic 9(9) binary value zero.
Linkage section.
01 XML-Doc pic X(500000).
01 G.
  02 A pic x(5).
  02 B pic s9(9) occurs 1 to unbounded depending on NB.
  02 C pic s9(9) occurs 1 to unbounded depending on NC.
Procedure division using XML-Doc.
  XML parse XML-Doc processing procedure CountElements
  Move length of G to Gsize
  Call "CEEGTST" using Heap0 Gsize Gptr omitted
  Set address of G to Gptr
  XML parse XML-doc processing procedure acquireContent
  ...
  Goback.
 CountElements.
  If xml-event = 'START-OF-ELEMENT'
   Evaluate xml-text
     When 'B'
      Add 1 to NB
     When 'C'
      Add 1 to NC
     When other
      Continue
   End-evaluate
  End-if.
End program XMLProc.