Working with REFER in generated PL/I structures
This topic describes how the REFER option is used to generate a compatible Enterprise PL/I structure for a variable-length XML array in the WSDL2PLI scenario.
- The PL/I source code that the WSDL2PLI code-generation process creates automatically.
- PL/I source code that you create to access the automatically generated structures.
A REFER example
A variable-length XSD schema array is one in which maxOccurs="unbounded" or where maxOccurs exceeds the limit set in the batch-processor property inlineMaxOccursLimit (see WSDL2ELSSpec). An example of such an array is shown in Figure 1:
<!-- XSD declaration: -->
<element name="planets" type="tns:PlanetsType"/>
<complexType name="PlanetsType">
<sequence>
<element name="planet_name" type="string" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
</complexType>
To implement the equivalent array in PL/I, the WSDL2PLI code-generation process creates two PL/I major structures, one for REFER object declarations and one for REFER subject declarations. Figure 2 and Figure 3 show the structures that would be generated for the XSD schema example in Figure 1:
The structure for object declarations specifies the maximum number of array items that can be allocated. For the significance of the suffixes _ref and _lim see Creation of PL/I identifiers:
Figure 2. Structure for object declarations /* PL/I REFER object declarations: */ 01 planets_ref UNALIGNED, /* number of planet_name entries to allocate space for */ 02 planet_name_lim SIGNED FIXED BINARY(31);
The structure for subject declarations maps the allocated space. For the significance of the suffixes _ptr, _lim, and _cnt see Creation of PL/I identifiers:
Figure 3. Structure for subject declarations /* PL/I REFER subject declarations: */ 01 planets UNALIGNED BASED(planets_ptr), /* saved number of planet_name refer objects allocated (read-only) */ 02 planet_name_lim SIGNED FIXED BINARY(31), /* count of planet_name array entries used */ 02 planet_name_cnt SIGNED FIXED BINARY(31), /* planet_name array with limit specified at allocation-time */ 02 planet_name (planets_ref.planet_name_lim REFER (planets.planet_name_lim)) CHAR(255) VARYING;
planets
is allocated, planets.planet_name_cnt
must
be set to the actual number of items in the array. Also the value
in planets.planet_name_cnt
must not exceed the value
in planets.planet_name_lim
./* Usage: */
planets_ref.planet_name_lim = 10;
allocate (planets) set (planets_ptr);
planets.planet_name(1) = “Mercury”;
planets.planet_name(2) = “Venus”;
planets.planet_name(3) = “Earth”;
planets.planet_name(4) = “Mars”;
planets.planet_name_cnt = 4;
A complex REFER example
This example defines a solar system structure containing an unbounded array of planets, with each planet structure containing an unbounded array of moons:
<!-- XSD declarations: -->
<element name="solar_system" type="tns:SolarSystemType" />
<complexType name="SolarSystemType">
<sequence>
<element name="planet" type="tns:PlanetType" minOccurs="0" maxOccurs="unbounded" />
</sequence>
</complexType>
<complexType name="PlanetType">
<sequence>
<element name="planet_name" type="string" minOccurs="1" maxOccurs="1" />
<element name="moon_name" type="string" minOccurs="1" maxOccurs="unbounded" />
</sequence>
</complexType>
To implement the equivalent arrays in PL/I, the WSDL2PLI code-generation process creates the two REFER object declarations and the two REFER subject declarations shown in Figure 6 and Figure 7:
Figure 6. Object declarations /* PL/I REFER object declarations: */ 01 solar_system_ref UNALIGNED, /* number of planet entries to allocate space for */ 02 planet_lim SIGNED FIXED BINARY(31), /* number of moon_name entries to allocate space for */ 2 moon_name_lim SIGNED FIXED BINARY(31);
Figure 7. Subject declarations /* PL/I REFER subject declarations: */ 01 solar_system UNALIGNED BASED(solar_system_ptr), /* saved number of planet refer objects allocated (read-only) */ 02 planet_lim SIGNED FIXED BINARY(31), /* saved number of moon_name refer object allocated (read-only) */ 02 moon_name_lim SIGNED FIXED BINARY(31), /* count of planet array entries used */ 02 planet_cnt SIGNED FIXED BINARY(31), /* planet array with limit specified at allocation-time */ 02 planet(solar_system_ref.planet_lim REFER (solar_system.planet_lim)), 03 planet_name CHAR(255) VARYING, /* count of moon_name[i] array entries used */ 03 moon_name_cnt SIGNED FIXED BINARY(31), /* moon_name array with limit specified at allocation */ 10 moon_name(solar_system_ref.moon_name_lim REFER (solar_system.moon_name_lim)) CHAR(255) VARYING;
planets.planet_cnt
, solar_system.planet(1).moon_name_cnt
,
and solar_system.planet(2).moon_name_cnt
must be
set to the actual number of items in the respective arrays./*Usage:*/
/* initialize major structure solar_system */
solar_system_ref.planet_lim = 4;
solar_system_ref.moon_name_lim = 2;
allocate (solar_system) set (solar_system_ptr);
solar_system.planet_cnt = 0;
/* create planet entry */
solar_system.planet(1) = “Earth”;
solar_system.planet(1).moon_name_cnt = 0;
solar_system.planet(1).moon_name(1) = “Luna”;
solar_system.planet(1).moon_name_cnt += 1;
solar_system.planet_cnt +=1; // 1
/* create planet entry */
solar_system.planet(2) = “Mars”;
solar_system.planet(2).moon_name_cnt = 0;
solar_system.planet(2).moon_name(1) = “Phobos”;
solar_system.planet(2).moon_name(2) = “Deimos”;
solar_system.planet(2).moon_name_cnt = 2;
solar_system.planet_cnt +=1; // 2
<solar_system>
<planet>
<planet_name>Earth</planet_name>
<moon_name>Luna</moon_name>
</planet>
<planet>
<planet_name>Mars</planet_name>
<moon_name>Phobos</moon_name>
<moon_name>Deimos</moon_name>
</planet>
</solar_system>
The minimum value of the REFER object solar_system_ref.moon_name_lim that will satisfy all repetitions of planet is 2. Setting the object value to 2 will cause space for two moon_name entries to be allocated for each planet entry. Because moon_name occurs only once in the first occurrence of the first planet entry, the counter solar_system.planet(1).moon_name_cnt should be set to 1 so that only the first moon_name entry is read.