Producing XML Output with Unicenter CA-Easytrieve - Part 2

Document ID : KB000055864
Last Modified Date : 14/02/2018
Show Technical Document Details

In a previous article, we introduced the new XML parameter for the REPORT statement and discussed how to put that together with the Extensible Stylesheet Language (XSL) and with a small amount of HTML to allow you to use CA Easytrieve to generate simple XML data in the same way you have been using it to generate reports for years. Now, we are going to go a little more in depth within the process.

When XML is processed and parsed, the tags within the XML file are used to delineate data. Especially when large amounts of data are involved, the appropriate grouping of records will vastly improve the performance of your web-based application. As an example, given the following XML snippet:

<RPT_REPORT>                       
  <RPT>                             
    <REGION>1</REGION>                  
    <BRANCH>01</BRANCH>                 
    <LAST_NAME>WIMN</LAST_NAME>    
    <FIRST_NAME>GLORIA</FIRST_NAME> 
    <DEPT>903</DEPT>                 
    <GROSS_PAY>   373.60 </GROSS_PAY> 
  </RPT>                            
  <RPT>                           
    .
    .
  </RPT> 
  <RPT>
    .
    .
  </RPT>
</RPT_REPORT>

To have a stylesheet process that data, you would typically use the following XSL statement:

      <xsl:template match="/">
<xsl:for-each select="RPT_REPORT/RPT">

This would, essentially, read every record within the XML file and process that information. The more records within the file, the more processing overhead occurs, especially if further testing for values within those records is done. The good news is that Easytrieve allows you to automatically add grouping levels within your XML data by using syntax you are already familiar with? the CONTROL statement in the REPORT sub-activity. If you remember from the last article, the Easytrieve statements to generate the above XML were:

      REPORT some-name XML
      LINE REGION BRANCH NAME-LAST NAME-FIRST DEPT PAY-GROSS

To add an additional grouping structure, simply change your code to the following:

      REPORT some-name XML
      CONTROL REGION
      LINE REGION BRANCH NAME-LAST NAME-FIRST DEPT PAY-GROSS

This produces the following XML:

<RPT_REPORT>
<REGION REGION='1'>   --Added  
  <RPT>                             
    <REGION>1</REGION>                  
    <BRANCH>01</BRANCH>                 
    <LAST_NAME>WIMN</LAST_NAME>    
    <FIRST_NAME>GLORIA</FIRST_NAME> 
    <DEPT>903</DEPT>                 
    <GROSS_PAY>   373.60 </GROSS_PAY> 
  </RPT>                            
  <RPT>                           
    .
    .
  </RPT>
</REGION>             --Added 
<REGION REGION='2'>   --Added  
  <RPT>
    .
    .
  </RPT>
</REGION>             --Added 
</RPT_REPORT>

This format of the XML now allows us to select and view a single REGION or to do different processing based upon the REGION value. For instance, the following XSL statements present a page in your web browser with a table of those people within REGION 1.

<?xml version="1.0"?>
<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    <xsl:output method="xml" encoding="WINDOWS-1252"/>
    <xsl:template match="/">
    <xsl:for-each select="RPT_REPORT/REGION">
    <xsl:choose>
        <xsl:when test='@REGION="1"'>
            <table ALIGN="center" WIDTH="90%">
            <xsl:for-each select="RPT">
                <TR>
                <xsl:choose>
                    <xsl:when test='*'>
                        <TH></TH>
                        <td bgcolor="Lightsalmon" ALIGN="center"><font size="2">
                         <xsl:value-of select="BRANCH"/></font></td>
                        <td bgcolor="Lightsalmon" ALIGN="center"><font size="2">
                         <xsl:value-of select="FIRST_NAME"/></font></td>
                        <td bgcolor="Lightsalmon" ALIGN="center"><font size="2">
                         <xsl:value-of select="LAST_NAME"/></font></td>
                        <td bgcolor="Lightsalmon" ALIGN="center"><font size="2">
                         <xsl:value-of select="DEPT"/></font></td>
                        <td bgcolor="Lightsalmon" ALIGN="center"><font size="2">
                         <xsl:value-of select="GROSS_PAY"/></font></td>
                    </xsl:when>
                </xsl:choose>
                </TR>
            </xsl:for-each>
            </table>
        </xsl:when>
    </xsl:choose>
    </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

The output from the above code would look like this:

imga

Of course, we wouldn't really put something that looks like this into production ? we should probably add some column headings to the table. To do that, we'll add the following statements after the <xsl:output/> line:

   <xsl:variable name="vHeading">
        <tr>
            <th></th>
            <th bgcolor="bisque"><font size="3" COLOR="Navy">Branch</font></th>
            <th bgcolor="bisque"><font size="3" COLOR="Navy">First Name</font></th>
            <th bgcolor="bisque"><font size="3" COLOR="Navy">Last Name</font></th>
            <th bgcolor="bisque"><font size="3" COLOR="Navy">Dept</font></th>
            <th bgcolor="bisque"><font size="3" COLOR="Navy">Salary</font></th>
        </tr>
    </xsl:variable>

This produces a re-usable table heading with a reference name of "vHeading", which can be used by inserting the following statement after the <table> statement:

<xsl:copy-of select="$vHeading"/>

We can also add a Table Title to our report by adding the following HTML statements before the <table> statement:

<FONT SIZE="5" COLOR="navy"><P ALIGN="Center">

REGION <xsl:value-of select="@REGION"/></P></FONT>

Finally, the order of the records being displayed should probably be enhanced. This can be done by placing the following sort statements after the <xsl:for-each select="RPT"> statement.

    <xsl:sort select="BRANCH" data-type="text" order="ascending"/>
<xsl:sort select="LAST_NAME" data-type="text" order="ascending"/>

Of course, you could have used Easytrieve to pre-sort the records before writing them out to the XML file. This becomes a choice of where it makes sense to have the processing occur. After all these changes, the results from the combination of the Easytrieve program and the XSL Stylesheet looks like this:

imgb

As you see, we now have a good start on producing a report, viewable within any Web Browser that is pretty much transparent to the actual data. We are using one of the strengths of Easytrieve to combine data from multiple sources to emit the XML file and then use a static stylesheet to display that information. Of course, there are a number of additional enhancements that the stylesheet could contain like presenting navigation links to each region that is displayed on the page but that becomes just more XSL processing and has nothing to do with Easytrieve.

The Easytrieve program used for this example was pretty well covered in the last article. However, I did add a couple of new statements, some of which are also new in the r11 release. Here is my program:

FILE PERSNL F(150) SYSNAME('c:\EZTPGMS\PERSNL')
 %PERSNL
FILE XMLRPT PRINTER SYSNAME 'TEST2.XML'
PROGRAM NAME XML2
    EXECUTE GENIT  
    LINK 'TEST2.XML'
    STOP    
JOB INPUT PERSNL NAME GENIT START SPROC 
        PRINT RPT
SPROC. PROC
    DISPLAY XMLRPT '<?xml-stylesheet type="text/xsl"' +
      ' href="EZTPersnl2.xsl"?>'
END-PROC
 REPORT RPT PRINTER XMLRPT XML
   CONTROL REGION
   LINE REGION BRANCH NAME-LAST NAME-FIRST DEPT PAY-GROSS

Of interest, not covered in the last article, is the CONTROL statement which provides grouping layers within the XML and also the PROGRAM, EXECUTE, and LINK statements. The PROGRAM statement is a super-activity within Easytrieve that can be used to conditionally invoke JOB or SORT activities. In this case, I first produce the XML file by executing the JOB GENIT and then I simply LINK to the XML file created. The result is the display of the generated data in your web browser based upon the stylesheet that we had created. This works within the Windows environment because of file associations but is clearly not z/OS friendly and shouldn't be ported to that environment.

I am hoping that I have provided information that gets your creative juices thinking about how this may apply within your organization. A key feature introduced with r11 and the Easytrieve WorkBench is the ability to offload Easytrieve program development from the mainframe. In the next issue, we'll delve into some of the issue involved with maintaining program portability between platforms and getting data available on the platform you're developing your programs on.