Transform XML into iSeries readable form, easily

This tips helps in the tedious task of writing RPGLE code to parse XML documents.

This Content Component encountered an error

Disoriented by SAX vs. DOM? Baffled by XML APIs? You are not alone. Writing RPGLE code to parse XML documents can be a tedious task. There is, however, a (free) utility called Xalan that will immensely ease your job, and let concentrate on the business rather than the bytes.

Xalan is a Java XSL parser, that will take as input 2 XML files: The first is the XML we want to transform, and the second is a XML file that defines the transformation. The transformation can output another XML, an HTML file, a PDF file (using special extensions).

Of special interest to iSeries professionals is the fact that a transformation can output a regular, flat text file, that is suited for import into a DB2 table.

You can find many examples of XSL transformations on the Web, but here is a real world example that is relevant in our context.

The Bank of Israel publishes a daily XML file with the currency rates.

With the attached code, you can find a sample of this file, and the XSL to transform it into a Comma Separated Values text file.

The result file can be imported into a DB2 table using CPYFRMIMPF command.

How to get Xalan to your iSeries computer?

-----------------------------------------------------------------

If you have VRR1, and have Java, then chances are that it is already installed.

Type WRKLNK OBJ('/QIBM/ProdData/OS400/xml/lib/*')

If you see the files xalan101.jar and xerces103.jar then you are already set up.

If you do not have the files, you can get them at here.

Note: This is an OLD version of Xalan. New version are available, but have not been tried by me, yet. If you decide to use a newer Xalan distribution, pay attention to the CLASSPATH variable.

Create a new IFS directory called XML:
MKDIR '/xml'

Transfer the ZIP file via FTP to the XML directory.

Run the following command (it's best to submit to batch):
QSH CMD('cd /xml; ajar -x -r xalan-j_1_0_1.zip')

About the attached code:

=================================================================
The CL program takes 5 parameters:
XML - The file to be translated.
XSL - The transformation description.
OUT - The result file.
CSSID - The code page of the result file.
VER - The AS/400 version. If *PRV, the script assumes that you installed Xalan manually according to the above listed instructions. Use *PRV in case you did not find the xalan101.jar file, even if you have 5.1 or higher.

XALAN *cmd:

=================================================================
/* CRTCMD CMD(XALAN) PGM(*LIBL/XALANCPP) ... */
CMD PROMPT('Translate XML using XSLT')
PARM KWD(XML) TYPE(*PNAME) LEN(256) MIN(1) +
CASE(*MIXED) PROMPT('Full XML file path')

PARM KWD(XSL) TYPE(*PNAME) LEN(256) MIN(1) +
CASE(*MIXED) PROMPT('Full XSL file path')

PARM KWD(out) TYPE(*PNAME) LEN(256) MIN(1) +
CASE(*MIXED) PROMPT('Full Result file path')

PARM KWD(CCSID) TYPE(*CHAR) LEN(7) PROMPT('CCSID +
of result file')

PARM KWD(VER) TYPE(*CHAR) LEN(7) RSTD(*YES) +
DFT(V5R1M0) VALUES(V5R1M0 V5R2M0 *PRV) +
PROMPT('OS400 release')
/* End of Command XALAN */

XALANCPP *PGM:

=============================================================
PGM PARM(&XML &XSL &OUT &CCSID &VER)
DCL VAR(&JAVA) TYPE(*CHAR) LEN(1024)

DCL VAR(&qshell) TYPE(*CHAR) LEN(1024)
DCL VAR(&XML) TYPE(*CHAR) LEN(256)
DCL VAR(&XSL) TYPE(*CHAR) LEN(256)
DCL VAR(&OUT) TYPE(*CHAR) LEN(256)
DCL VAR(&CCSID) TYPE(*CHAR) LEN(7)
DCL VAR(&VER) TYPE(*CHAR) LEN(6)

/* Prepare java call */
IF COND(&VER = '*PRV') THEN(DO)

CHGVAR VAR(&JAVA) VALUE('java -classpath +
/xml/xalan_1_0_1/xalan.jar:/xml/xalan_1_0_1+

/xerces.jar:. + org.apache.xalan.xslt.Process ' *BCAT +
'-IN ' *BCAT &XML *BCAT ' -XSL ' *BCAT +
&XSL *BCAT ' -OUT ' *BCAT &OUT *BCAT ' +
-TEXT')

enddo
ELSE CMD(DO)
CHGVAR VAR(&JAVA) VALUE('java -classpath +
/QIBM/ProdData/OS400/xml/lib/xalan101.jar:/+
QIBM/ProdData/OS400/xml/lib/xerces103.jar:. +
org.apache.xalan.xslt.Process ' *BCAT +
'-IN ' *BCAT &xml *BCAT ' -XSL ' *BCAT +
&xsl *BCAT ' -OUT ' *BCAT &out *BCAT ' -TEXT'
enddo

STRQSH CMD(&JAVA)
/* Change CCSID of OUT file
CHGVAR VAR(&QSHELL) VALUE('setccsid' *bcat &ccsid *BCAT &out)
STRQSH CMD(&qshell)

RETURN
EXIT: ENDPGM

/* End of Program XALANCPP */

Sample XML to translate:

Note: The encoding in the original XML file is wrong.

==============================================================

 
<?xml version="1.0" encoding="iso-8859-8" standalone="yes"?>  
<CURRENCIES>                            
<LAST_UPDATE>  2002-10-21</LAST_UPDATE>   
<CURRENCY>                              
<NAME>  unit</NAME>                       
<UNIT>  1</UNIT>                          
<COUNTRY>  Currency basket</COUNTRY>      
<RATE>  4.938</RATE>                      
<CHANGE>  -0.315</CHANGE>                 
</CURRENCY>                             
<CURRENCY>                              
<NAME>  dollar</NAME>                     
<UNIT>  1</UNIT>                          
<COUNTRY>  USA</COUNTRY>            
<RATE>  4.745</RATE>                
<CHANGE>  -0.357</CHANGE>           
</CURRENCY>                       
<CURRENCY>                        
<NAME>  pound</NAME>                
<UNIT>  1</UNIT>                    
<COUNTRY>  Great Britain</COUNTRY>  
<RATE>  7.3398</RATE>               
<CHANGE>  -0.473</CHANGE>           
</CURRENCY>                       
<CURRENCY>                        
<NAME>  yen</NAME>                  
<UNIT>  100</UNIT>                  
<COUNTRY>  Japan</COUNTRY>          
<RATE>  3.8057</RATE>                       
<CHANGE>  0.076</CHANGE>                    
</CURRENCY>         <CURRENCY>                                <NAME>  euro</NAME>                         
<UNIT>  1</UNIT>                            
<COUNTRY>  European Monetary Union</COUNTRY>  
<RATE>  4.62</RATE>                         
<CHANGE>  -0.244</CHANGE>  
</CURRENCY>                               
<CURRENCY>  
<NAME>  dollar</NAME>                       
<UNIT>  1</UNIT>  
<COUNTRY>  Australia</COUNTRY>  
<RATE>  2.6299</RATE>           
<CHANGE>  0.221</CHANGE>        
</CURRENCY>                   
<CURRENCY>                    
<NAME>  dollar</NAME>           
<UNIT>  1</UNIT>                
<COUNTRY>  Canada</COUNTRY>     
<RATE>  3.0254</RATE>           
<CHANGE>  -0.228</CHANGE>       
</CURRENCY>                   
<CURRENCY>                    
<NAME>  krone</NAME>            
<UNIT>  1</UNIT>                
<COUNTRY>  Denmark</COUNTRY>    
<RATE>  0.6219</RATE>               
<CHANGE>  -0.209</CHANGE>           
</CURRENCY>                       
<CURRENCY>                        
<NAME>  krone</NAME>                
<UNIT>  1</UNIT>                    
<COUNTRY>  Norway</COUNTRY>         
<RATE>  0.6248</RATE>               
<CHANGE>  0.016</CHANGE>            
</CURRENCY>                       
<CURRENCY>                        
<NAME>  rand</NAME>                 
<UNIT>  1</UNIT>                    
<COUNTRY>  South Africa</COUNTRY>   
<RATE>  0.4621</RATE>             
<CHANGE>  0.304</CHANGE>          
</CURRENCY>                     
<CURRENCY>                      
<NAME>  krona</NAME>              
<UNIT>  1</UNIT>                  
<COUNTRY>  Sweden</COUNTRY>       
<RATE>  0.5093</RATE>             
<CHANGE>  0.118</CHANGE>          
</CURRENCY>                     
<CURRENCY>                      
<NAME>  franc</NAME>              
<UNIT>  1</UNIT>                  
<COUNTRY>  Switzerland</COUNTRY>  
<RATE>  3.1438</RATE>          
<CHANGE>  -0.314</CHANGE>      
</CURRENCY>                  
<CURRENCY>                   
<NAME>  dinar</NAME>           
<UNIT>  1</UNIT>               
<COUNTRY>  Jordan</COUNTRY>    
<RATE>  6.6869</RATE>          
<CHANGE>  -0.356</CHANGE>      
</CURRENCY>                  
<CURRENCY>                   
<NAME>  pound</NAME>           
<UNIT>  10</UNIT>              
<COUNTRY>  Lebanon</COUNTRY>   
<RATE>  0.0314</RATE>       
<CHANGE>  -0.317</CHANGE>   
</CURRENCY>               
<CURRENCY>                
<NAME>  pound</NAME>        
<UNIT>  1</UNIT>            
<COUNTRY>  Egypt</COUNTRY>  
<RATE>  1.0243</RATE>       
<CHANGE>  -0.088</CHANGE>   
</CURRENCY>               
</CURRENCIES>             
<!--- End of Sample XML file --->  

Sample XSL file:
====================
<?xml version="1.0"?>   
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">  
<xsl:template match="CURRENCIES">     
<xsl:for-each select="CURRENCY">      
  <xsl:apply-templates select="." />  
</xsl:for-each>                       
</xsl:template>                       
<xsl:template match="CURRENCY">       
<xsl:variable name="dt" select="/CURRENCIES/LAST_UPDATE"/>  
<xsl:value-of select="concat(substring($dt,1,4), substring($dt,6,2), substring($dt,9,2))"/>   
 <xsl:text>  , </xsl:text>        
<xsl:value-of select="NAME"/>   
 <xsl:text>  , </xsl:text>        
<xsl:value-of select="UNIT"/>   
 <xsl:text>  , </xsl:text>           
<xsl:value-of select="COUNTRY"/>   
 <xsl:text>  , </xsl:text>           
<xsl:value-of select="RATE"/>      
 <xsl:text>  , </xsl:text>           
<xsl:value-of select="CHANGE"/>    
 <xsl:text>  
</xsl:text>        
</xsl:template>                    
</xsl:stylesheet>                  
<  !--- End of sample XSL ----->  

This was first published in October 2002

Dig deeper on iSeries CL programming

0 comments

Oldest 

Forgot Password?

No problem! Submit your e-mail address below. We'll send you an email containing your password.

Your password has been sent to:

-ADS BY GOOGLE

SearchEnterpriseLinux

SearchDataCenter

Close