XMLi: generation of XML or HTML from within RPG

XMLi is a cool open source suite of service programs which enable the easy generation of XML or HTML from within RPG.

XMLi1 enables the building of XML within RPG using procedure calls. Data can be written to your program variables or pointers. XMLi2 provides an XML-based scripting language that makes XML generation easy. Simply write a template of your desired XML/HTML and use imbedded SQL queries to build your data. Pass parameters to the template from your RPG to be used in your SQL queries. Conditional logic is provided by IF and CHOOSE blocks, and looping constructs are provided by DOW/DOU/FOR loops. Looping through SQL queries is provided using FOR-EACH. Data can be written to the IFS, standard output, or passed to a call-back procedure.

Extend the XMLi language via your own extensions written in RPG. These allow you to call your own business logic from within a running template.

100% ILE RPG - source available as a download at Sourceforge.net. Runs on IBM i (iSeries, Series, AS/400). Some of the examples provided in package are reproduced below...

Features

  • XMLi1 - Utility for building XML within RPG Programs
  • XMLI2 - Utility for generation of xml from a template


Example 01: Use XMLi to write XML to a variable

	 
      // file: EXAMPLE_H
      // common header code
	  
      // Print formatted string to the console...
     d example_print...
     d                 pr                  extproc('printf')
     d                                 *   value options(*string)

      // Get character from keyboard buffer...
     d example_pauseScreen...
     d                 pr            10i 0 extproc('getchar')


     // Program constants...
     d crlf            c                   const(X'0d25') 
      * file: EXAMPLE01
      * XMLI1: Simply write XML to a character variable     
	  *
	 H OPTION(*NODEBUGIO:*NOEXPDDS:*SRCSTMT)
     H DFTACTGRP(*NO) ACTGRP('QILE')

      **************************************************************************
      * This example uses XMLi to write XML to a variable within this program.
      *
      * To use XMLi you simply tell it to use your variable and then tell it
      * what you want to write. XMLi works out where to write and how to format
      * the XML for you.
      * When you have created your XML simply tell XMLi to no longer use your
      * variable.
      *
      * This example will print the contents of the variable to the console and IFS
      **************************************************************************

      // BNDDIR for XMLI1...
     H BNDDIR('XMLILIB/XMLI1')

      // BNDDIR for displaying example results (DO NOT USE IN PRODUCTION)
     H BNDDIR('QC2LE')

      **********************************************************************
      // Copybook for XMLI1...       
      /include xmlilib/qcpylesrc,xmli1_h
      *********************************************************************

      // Copybook for displaying example results (DO NOT USE IN PRODUCTION)
      /include xmlilib/qrpglesrc,example_h
      **********************************************************************

      // Program variables...
     d char1024        s           1024a
      *********************************************************************
      /free

       // Set the XML format to simple...
       xmli_setFormat(XML_FORMAT_SIMPLE);

       // Initialise the variable and tell xmli you want to write xml to it...
       char1024 = *blanks;
       xmli_useVariable(char1024);

       // Build some XML...
       xmli_openTag('root');
       xmli_addAttribute('timestamp' : %char(%timestamp));
       xmli_addElement('element1' : 'value1');
       xmli_addElement('element2' : 'value2');
       xmli_addElement('element3' : 'value3');
       xmli_closeTag('root');

       // The XML has now been written to the char1024 variable...

       // Tell XMLi you don't want it to use the variable anymore...
       xmli_freeVariable(char1024);
       // At this point the xml has been written to the variable by XMLi
       // and XMLi no longer references it: You are free to do whatever
       // you wish with it now. This program simply prints the contents
       // to the console for display...

       // Print the value inside the variable to the console...
       example_print( 'The value inside the char1024 variable is:' + CRLF);
       example_print( %trim(char1024) + CRLF);
       example_print( 'Notice the XML is in simple format?'+ CRLF);
       example_print( 'The XML has a CRLF at the end of each line.' +
                      ' You can remove whitespace by calling' +
                      ' xmli_setFormat(XML_FORMAT_NONE) before building' +
                      ' your XML.' + CRLF);
       example_print( 'Press ANY KEY to close the window' + CRLF);
       example_pauseScreen();

       *INLR = *on;
       return;

      /end-free 
Output to screen:
The value inside the char1024 variable is:                                   
                                
value1                                                  
value2                                                  
value3                                                  
                                                                      
Notice the XML is in simple format?                                          
The XML has a CRLF at the end of each line. You can remove whitespace by call
ing xmli_setFormat(XML_FORMAT_NONE) before building your XML.                
Press ANY KEY to close the window



Example 02: XMLI1: A more complicated XML (character variable)

     H OPTION(*NODEBUGIO:*NOEXPDDS:*SRCSTMT)
     H DFTACTGRP(*NO) ACTGRP('QILE')

      **************************************************************************
      * This example uses XMLi to write XML to a variable within this program.
      *
      * To use XMLi you simply tell it to use your variable and then tell it
      * what you want to write. XMLi works out where to write and how to format
      * the XML for you.
      * When you have created your XML simply tell XMLi to no longer use your
      * variable.
      *
      * This example will print the contents of the variable to the console.
      **************************************************************************

      // BNDDIR for XMLI1...
     H BNDDIR('XMLILIB/XMLI1')

      // BNDDIR for displaying example results ( 
     H BNDDIR('QC2LE')

      **********************************************************************
      // Copybook for XMLI1...
      /include xmlilib/qcpylesrc,xmli1_h
      *********************************************************************

      // Copybook for displaying example results  
      /include xmlilib/qrpglesrc,example_h
      **********************************************************************

      // Program variables...
     d char1024        s           1024a


     d i               s             10i 0
      *********************************************************************
      /free

       // Set the XML format to simple...
       xmli_setFormat(XML_FORMAT_SIMPLE);

       // Initialise the variable and tell xmli you want to write xml to it...
       char1024 = *blanks;
       xmli_useVariable(char1024);

       // Build some XML...
       xmli_openTag('Library');
         xmli_addAttribute('version' : 'version1.2.0');
         xmli_addAttribute('timestamp' : %char(%timestamp));

         // List a few categories...
         xmli_openTag('Categories');
         for i = 1 to 3;
           xmli_addElement('Category': %char(i*3));
         endfor;
         xmli_closeTag('Categories');

         // List a few authors...
         xmli_openTag('Authors');
         for i = 1 to 3;
           xmli_openTag('Author');
           xmli_addAttribute('index': %char(i*2));
           xmli_addData('Author Name Goes Here');
           xmli_closeTag('Author');
         endfor;
         xmli_closeTag('Authors');

         // List a few books...
         xmli_openTag('Books');
         for i = 1 to 3;
           xmli_openTag('Book');
           xmli_addAttribute('isbn' : %editc(i:'X'));
             xmli_openTag('Details');
               xmli_addElement('Author' : %char(i*2));
               xmli_addElement('Category' : %char(i*3));
               xmli_addElement('Blurb'
                              :'Something about book ' + %editc(i:'X'));
             xmli_closeTag('Details');
           xmli_closeTag('Book');
         endfor;
       xmli_closeTag('Books');

       xmli_closeTag('Library');

       // The XML has now been written to the char1024 variable...

       // Tell XMLi you don't want it to use the variable anymore...
       xmli_freeVariable(char1024);

       // At this point the xml has been written to the variable by XMLi
       // and XMLi no longer references it: You are free to do whatever
       // you wish with it now. This program simply prints the contents
       // to the console for display...

       // write to  IFS
       xmli_writeToFile( '/HOME/XML_TEST/Example02.xml'
                        : %addr(char1024)
                        : xmli_getCurrentLength()
                        : XML_ENCODING_UTF8);

       // Print the value inside the variable to the console...
       example_print( 'The value inside the char1024 variable is:' + CRLF);
       example_print( %trim(char1024) + CRLF);
       example_print( 'Press ANY KEY to close the window' + CRLF);
       example_pauseScreen();

       *INLR = *on;
       return;

      /end-free 	 
output to IFS file:

<Library version="version1.2.0" timestamp="2024-02-04-16.58.26.330318">
<Categories>
<Category>3</Category>
<Category>6</Category>
<Category>9</Category>
</Categories>
<Authors>
<Author index="2">Author Name Goes Here</Author>
<Author index="4">Author Name Goes Here</Author>

<Author index="6">Author Name Goes Here</Author>
</Authors>
<Books>
<Book isbn="0000000001">
<Details>
<Author>2</Author>
<Category>3</Category>
<Blurb>Something about book 0000000001</Blurb>
</Details>
</Book>
<Book isbn="0000000002">
<Details>
...
<Author>6</Author>
<Category>9</Category>
<Blurb>Something about book 0000000003</Blurb>
</Details>
</Book>
</Books>
</Library>


Example 03: XMLI1: Writing a SOAP request to a char variable

     H OPTION(*NODEBUGIO:*NOEXPDDS:*SRCSTMT)
     H DFTACTGRP(*NO) ACTGRP('QILE')

      **************************************************************************
      * This example uses XMLi to write XML to a variable within this program.
      *
      * To use XMLi you simply tell it to use your variable and then tell it
      * what you want to write. XMLi works out where to write and how to format
      * the XML for you.
      * When you have created your XML simply tell XMLi to no longer use your
      * variable.
      *
      * The following SOAP Envelope is created in HTTPAPI EXAMPLE18
      *
      *   '<?xml version="1.0" encoding="iso-8859-1" standalone="no"?>'
      *  +'<SOAP:Envelope'
      *  +'    xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/"'
      *  +'    xmlns:tns="http://www.webserviceX.NET/">'
      *  +'<SOAP:Body>'
      *  +'  <tns:ConversionRate>'
      *  +'    <tns:FromCurrency>'+ %trim(Country1) +'</tns:FromCurrency>'
      *  +'    <tns:ToCurrency>'+ %trim(Country2) + '</tns:ToCurrency>'
      *  +'  </tns:ConversionRate>'
      *  +'</SOAP:Body>'
      *  +'</SOAP:Envelope>';
      *
      * This example will build the envelope in a variable and print the
      * the contents of the variable to the console.
      **************************************************************************

      // BNDDIR for XMLI1...
     H BNDDIR('XMLILIB/XMLI1')

      // BNDDIR for displaying example results (DO NOT USE IN PRODUCTION)
     H BNDDIR('QC2LE')

      **********************************************************************
      // Copybook for XMLI1...      
      /include xmlilib/qcpylesrc,xmli1_h
      *********************************************************************

      // Copybook for displaying example results (DO NOT USE IN PRODUCTION)
      /include xmlilib/qrpglesrc,example_h
      **********************************************************************

      // Program variables...
     d char1024        s           1024a

     d Country1        s              3A   inz('USD')
     d Country2        s              3A   inz('JPY')
      *********************************************************************
      /free

       // Set the XML format to pretty...
       xmli_setFormat(XML_FORMAT_PRETTY);

       // Initialise the variable and tell xmli you want to write xml to it...
       char1024 = *blanks;
       xmli_useVariable(char1024);

       // Build some XML...
       xmli_addDeclaration(XML_ENCODING_ISO_8859_1
                       :XML_STANDALONE_NO);
       xmli_openTag('SOAP:Envelope');
         xmli_addAttribute('xmlns:SOAP'
                          : 'http://schemas.xmlsoap.org/soap/envelope/');
         xmli_addAttribute('xmlns:tns'
                          : 'http://www.webserviceX.NET/');
         xmli_openTag('SOAP:Body');
         xmli_openTag('tns:ConversionRate');
         xmli_addElement('tns:FromCurrency' : %trim(Country1) );
         xmli_addElement('tns:ToCurrency' : %trim(Country2) );
         xmli_closeTag('tns:ConversionRate');
         xmli_closeTag('SOAP:Body');

       xmli_closeTag('SOAP:Envelope');

       // !! The XML has now been written to the char1024 variable...!!
       // Use the address of char1024 and the data length to write to the IFS...

       xmli_writeToFile( '/HOME/XML_TEST/Example03.xml'
                        : %addr(char1024)
                        : xmli_getCurrentLength()
                        : XML_ENCODING_UTF8);


       // Tell XMLi you don't want it to use the variable anymore...
       xmli_freeVariable(char1024);

       // At this point the xml has been written to the variable by XMLi
       // and XMLi no longer references it: You are free to do whatever
       // you wish with it now. This program simply prints the contents
       // to the console for display...

       // Print the value inside the variable to the console...
       example_print( 'The value inside the char1024 variable is:' + CRLF);
       example_print( %trim(char1024) + CRLF);
       example_print( 'Note that this format is pretty format' + CRLF);
       example_print( 'Press ANY KEY to close the window' + CRLF);
       example_pauseScreen();

       *INLR = *on;
       return;

      /end-free 

output to IFS file

<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="http://www.webserviceX.NET/">
  <SOAP:Body>
    <tns:ConversionRate>
      <tns:FromCurrency>USD</tns:FromCurrency>
      <tns:ToCurrency>JPY</tns:ToCurrency>
    </tns:ConversionRate>
  </SOAP:Body>
</SOAP:Envelope>


Example 04: XMLI1: Processing Instructions and Comments

     H OPTION(*NODEBUGIO:*NOEXPDDS:*SRCSTMT)
     H DFTACTGRP(*NO) ACTGRP('QILE')

      **************************************************************************
      * This example uses XMLi to write XML to a variable within this program.
      *
      * To use XMLi you simply tell it to use your variable and then tell it
      * what you want to write. XMLi works out where to write and how to format
      * the XML for you.
      * When you have created your XML simply tell XMLi to no longer use your
      * variable.
      *
      * This program shows how to write processing instructions and comments
      * to the XML.
      * <!-- Comments have a standard format -->
      * <?Processing Instructions usually have a name and a set of attributes ?>
      **************************************************************************

      // BNDDIR for XMLI1...
     H BNDDIR('XMLILIB/XMLI1')

      // BNDDIR for displaying example results (DO NOT USE IN PRODUCTION)

     H BNDDIR('QC2LE')


     **********************************************************************
      // Copybook for XMLI1...
      /include xmlilib/qcpylesrc,xmli1_h
      *********************************************************************

      // Copybook for displaying example results (DO NOT USE IN PRODUCTION)
      /include xmlilib/qrpglesrc,example_h
      **********************************************************************

      // Program variables...
     d char1024        s           1024a

      *********************************************************************
      /free

       // Set the XML format to simple...
       xmli_setFormat(XML_FORMAT_SIMPLE);

       // Initialise the variable and tell xmli you want to write xml to it...
       char1024 = *blanks;
       xmli_useVariable(char1024);

       // Build some XML with processing instructions and comments...
       xmli_addDeclaration(XML_ENCODING_ISO_8859_1);
       xmli_openTag('Example04');
         xmli_addComment('Below is an exampe Processing Instruction (PI)');
         xmli_addPI('example attr1="value" attr2="value"');
         xmli_addComment('Below is a PI used in a XSL stylesheet');
         xmli_addPI('xml-stylesheet href="style.css" type="text/css"');
         xmli_addComment('The XML Declaration is a PI!');
       xmli_closeTag('Example04');

       // !! The XML has now been written to the char1024 variable...!!
       // Use the address of char1024 and the data length to write to the IFS...

       // write to IFS file 
       xmli_writeToFile( '/HOME/XML_TEST/Example04.xml'
                        : %addr(char1024)
                        : xmli_getCurrentLength()
                        : XML_ENCODING_UTF8);

       // Tell XMLi you don't want it to use the variable anymore...
       xmli_freeVariable(char1024);

       // At this point the xml has been written to the variable by XMLi
       // and XMLi no longer references it: You are free to do whatever
       // you wish with it now. This program simply prints the contents
       // to the console for display...

       // Print the value inside the variable to the console...
       example_print( 'The value inside the char1024 variable is:' + CRLF);
       example_print( %trim(char1024) + CRLF);
       example_print( 'Press ANY KEY to close the window' + CRLF);
       example_pauseScreen();

       *INLR = *on;
       return;

      /end-free 

Output to IFS:

<?xml version="1.0" encoding="ISO-8859-1"?>
<Example04>
<!-- Below is an exampe Processing Instruction (PI) -->
<?example attr1="value" attr2="value"?>
<!-- Below is a PI used in a XSL stylesheet -->
<?xml-stylesheet href="style.css" type="text/css"?>
<!-- The XML Declaration is a PI! -->
</Example04>


Example 05: XMLI1: Processing Instructions and Comments

	
     H OPTION(*NODEBUGIO:*NOEXPDDS:*SRCSTMT)
     H DFTACTGRP(*NO) ACTGRP('QILE')

      **************************************************************************
      * This program shows how to work with Entity References.
      * The five entity references included in the standard are:
      * '   &apos;
      * "   &quot;
      * >   &gt;
      * <   &lt;
      * &   &amp;
      * By default XMLi replaces all entities with their reference.
      **************************************************************************

      // BNDDIR for XMLI1...
     H BNDDIR('XMLILIB/XMLI1')

      // BNDDIR for displaying example results (DO NOT USE IN PRODUCTION)
     H BNDDIR('QC2LE')

      **********************************************************************
      // Copybook for XMLI1...      
      /include xmlilib/qcpylesrc,xmli1_h
      *********************************************************************

      // Copybook for displaying example results (DO NOT USE IN PRODUCTION)
      /include xmlilib/qrpglesrc,example_h

      **********************************************************************

      // Program variables...
     d char1024        s           1024a

      // Samples have entities in them - Apostrophe needs escaping in RPG!!!
     d sampleText1     s             32a   inz('Entities to handle: "<>&''')
     d sampleText2     s             32a   inz('Entities: "<>&''')
     d sampleText3     s             32a   inz('O''Reilly & O''Reilly')
      *********************************************************************
      /free


      // Set the XML format to pretty...
       xmli_setFormat(XML_FORMAT_PRETTY);

       // Initialise the variable and tell xmli you want to write xml to it...
       char1024 = *blanks;
       xmli_useVariable(char1024);

       // Build some XML with entity references replacing the entities...
       xmli_openTag('Example05');
         xmli_addComment( %trim(sampleText1) );
         xmli_addComment('Comments are not considered part of the markup.');
         xmli_addComment('See how entities do not need escaping in comments?');
         xmli_addComment('They are escaped in markup by default: See below.');
         xmli_addElement('SampleText2' : %trim(sampleText2) );
         xmli_addElement('SampleText3' : %trim(sampleText3) );
         xmli_addComment('Even attributes need entities escaping:');
         xmli_openTag('SampleTag' : XML_TAG_SELF_CLOSE_YES);
           xmli_addAttribute('sampleAttribute' : %trim(sampleText2) );
       xmli_closeTag('Example05');

       //  The XML has now been written to the char1024 variable...

       // Use the address of char1024 and the data length to write to the IFS...

       xmli_writeToFile( '/HOME/XML_TEST/Example05.xml'
                       : %addr(char1024)
                       : xmli_getCurrentLength()
                       : XML_ENCODING_UTF8);

       // Tell XMLi you don't want it to use the variable anymore...
       xmli_freeVariable(char1024);

       // At this point the xml has been written to the variable by XMLi
       // and XMLi no longer references it: You are free to do whatever
       // you wish with it now. This program simply prints the contents
       // to the console for display...

       // Print the value inside the variable to the console...
       example_print( 'The value inside the char1024 variable is:' + CRLF);
       example_print( %trim(char1024) + CRLF);
       example_print( 'Press ANY KEY to close the window' + CRLF);
       example_pauseScreen();

       *INLR = *on;
       return;


     /end-free 
Output to IFS
<Example05>
  <!-- Entities to handle: "<>&' -->
  <!-- Comments are not considered part of the markup. -->
  <!-- See how entities do not need escaping in comments? -->
  <!-- They are escaped in markup by default: See below. -->
  <SampleText2>Entities: &quot;&lt;&gt;&amp;&apos;</SampleText2>
  <SampleText3>O&apos;Reilly &amp; O&apos;Reilly</SampleText3>
  <!-- Even attributes need entities escaping: -->
  <SampleTag sampleAttribute="Entities: &quot;&lt;&gt;&amp;&apos;"/>
</Example05>


Example 07: Writing XML to 2 variables and combining

     H OPTION(*NODEBUGIO:*NOEXPDDS:*SRCSTMT)
     H DFTACTGRP(*NO) ACTGRP('QILE')

      **************************************************************************
      * This example uses XMLi to write XML to 2 variables within this program.
      * The data from one is added to the other. The result is written to the IFS
      * using the addrss and current data length - more accurate method.
      *
      * The XML is written to /XMLI/Examples/Results/Example07.xml
      **************************************************************************

      // BNDDIR for XMLI1...
     H BNDDIR('XMLILIB/XMLI1')
      **********************************************************************
      // Copybook for XMLI1...      
      /include xmlilib/qcpylesrc,xmli1_h
      *********************************************************************

      // Program variables...
     d char1024        s           1024a
     d char512         s            512a

      // Variables to hold address and length of data within char1024...
     d pChar1024       s               *    inz(%addr(char1024))
     d char1024Len     s             10i 0
     d ret             s             10i 0

      *********************************************************************
      /free

       // Switch formatting off (no whitespace between elements)...
       // *** This is the most compact format ***
       xmli_setFormat(XML_FORMAT_NONE);

       xmli_useVariable(char1024);

       // Build some XML with entity references replacing the entities...
       xmli_openTag('Example07');
         xmli_addElement('Element1' : 'value1');
         xmli_addElement('Element2' : 'value2');


         // We can use another variable in XMLi...
         xmli_useVariable(char512);

         // Any XML written now will go onto char512 and NOT char1024..!!!
         // *** This is because char512 is now the current variable ***

         xmli_addElement('Element3' : 'value3');
         xmli_addElement('Element4' : 'value4');
       xmli_closeTag('Example07');

       // We have written the above xml fragment to char512 and now we free it...
       xmli_freeVariable(char512);

       // Any XML written now will go onto char1024 again..!!!
       // *** This is because char1024 is now the current variable ***

       // Add the data from char512 to char1024 but DO NOT escape the markup...
       xmli_addData(%trim(char512) : XML_ESCAPE_ENTITY_REFS_NO);

       // Use the address of char1024 and the data length to write to the IFS...
       ret = xmli_writeToFile(  '/HOME/XML_TEST/Example07.xml'
                        : %addr(char1024)
                        : xmli_getCurrentLength()
                        : XML_ENCODING_UTF8);

       // At this point the XML should contain what was in char1024 and char512..
       // We can free char1024 now (If we free it earlier the retrieval of current
       // length would be zero - we would have no current variable)...
       xmli_freeVariable(char1024);

       *INLR = *on;
       return;

      /end-free 

Output to file:

<Example07><Element1>value1</Element1><Element2>value2</Element2><Element3>value3</Element3><Element4>value4</Element4></Example07>


Example 08: XMLI1: Writing XML to streamfile in pretty format

	 
     H OPTION(*NODEBUGIO:*NOEXPDDS:*SRCSTMT)
     H DFTACTGRP(*NO) ACTGRP('QILE')

     **************************************************************************
      * This example uses XMLi to write XML to a variable within this program.
      * The data from the variable is written to a streamfile in 'pretty' format.
      * Pretty format presenta the XML in a more human-readable format with each element 
      * on its own line with indentation of hierarchies.
      *
      * The XML is written to /HOME/XML_TEST/Example08.xml
      **************************************************************************

      // BNDDIR for XMLI1...
     H BNDDIR('XMLILIB/XMLI1')
      **********************************************************************
      // Copybook for XMLI1...      
      /include xmlilib/qcpylesrc,xmli1_h
      *********************************************************************

      // Program variables...
     d char1024        s           1024a
     d char512         s            512a

      // Variables to hold address and length of data within char1024...
     d pChar1024       s               *    inz(%addr(char1024))
     d char1024Len     s             10i 0

      *********************************************************************
      /free

       // Switch to pretty format (2 spaces per indent)...
       xmli_setFormat(XML_FORMAT_PRETTY);

       xmli_useVariable(char1024);

       // Build some XML with entity references replacing the entities...
       xmli_openTag('Example08');
         xmli_openTag('Element1');
           xmli_addElement('Element1_1' : 'value1_1');
           xmli_addElement('Element1_2' : 'value1_2');
         xmli_closeTag('Element1');
         xmli_addElement('Element2' : 'value2');
         xmli_addElement('Element3' : 'value3');
         xmli_addElement('Element4' : 'value4');
         xmli_openTag('Element5');
           xmli_addElement('Element5_1' : 'value5_1');
           xmli_addElement('Element5_2' : 'value5_2');
           xmli_openTag('Element5_3');
             xmli_addElement('Element5_3_1' : 'value5_3_1');
             xmli_addElement('Element5_3_2' : 'value5_3_2');
           xmli_closeTag('Element5_3');
         xmli_closeTag('Element5');
       xmli_closeTag('Example08');

       // Use the address of char1024 and the data length to write to the IFS...
       xmli_writeToFile( '/HOME/XML_TEST/Example08.xml'
                        : %addr(char1024)
                        : xmli_getCurrentLength()
                        : XML_ENCODING_UTF8);

       // Free the variable...
       xmli_freeVariable(char1024);

       *INLR = *on;
       return;

      /end-free 

Output to IFS:

<Example08>
  <Element1>
    <Element1_1>value1_1</Element1_1>
    <Element1_2>value1_2</Element1_2>
  </Element1>
  <Element2>value2</Element2>
  <Element3>value3</Element3>
  <Element4>value4</Element4>
  <Element5>
    <Element5_1>value5_1</Element5_1>
    <Element5_2>value5_2</Element5_2>
    <Element5_3>
      <Element5_3_1>value5_3_1</Element5_3_1>
      <Element5_3_2>value5_3_2</Element5_3_2>
    </Element5_3>
  </Element5>
</Example08>


Example 09: XMLI1: Write XML to a pointer

	 

     H OPTION(*NODEBUGIO:*NOEXPDDS:*SRCSTMT)
     H DFTACTGRP(*NO) ACTGRP('QILE')

      **************************************************************************
      * This example uses XMLi to write XML to a pointer within this program.
      *
      * To use XMLi you simply tell it to use your pointer and then tell it
      * what you want to write. XMLi works out where to write and how to format
      * the XML for you.
      * When you have created your XML simply tell XMLi to no longer use your
      * pointer.
      *
      * This example will print the contents of the pointer to the console.
      **************************************************************************

      // BNDDIR for XMLI1...
     H BNDDIR('XMLILIB/XMLI1')

      // BNDDIR for displaying example results (DO NOT USE IN PRODUCTION)
     H BNDDIR('QC2LE')

      **********************************************************************
      // Copybook for XMLI1...
      /include xmlilib/qcpylesrc,xmli1_h
      *********************************************************************

      // Copybook for displaying example results (DO NOT USE IN PRODUCTION)
      /include xmlilib/qrpglesrc,example_h
      **********************************************************************

      // Program variables...
     d pointer         s               *
     d xmlData         s            512a   based(pointer)

     d xmlPointer      s               *
     d xmlLength       s             10i 0
      *********************************************************************
      /free

       // Allocate some memory to the pointer and tell XMLi you want to use it.
       // When using pointers you must tell XMLi how much memory you have allocated...
       pointer = %alloc(512);
       xmli_usePointer(pointer : 512);
       xmli_setFormat(XML_FORMAT_SIMPLE);

       // Build some XML...
       xmli_openTag('root');
         xmli_addAttribute('timestamp' : %char(%timestamp));
         xmli_addElement('element1' : 'value1');
         xmli_addElement('element2' : 'value2');
         xmli_addElement('element3' : 'value3');
         xmli_openTag('sub-element');
           xmli_addAttribute('attr1' : 'Attribute Value 1');
           xmli_addAttribute('attr2' : %char(%date():*USA));
           xmli_addData('Here is some data to go in sub-element');
         xmli_closeTag('sub-element');
       xmli_closeTag('root');

       // At this point the xml has been written to the pointer by XMLi
       // If the current data is to be retrieved then the pointer needs
       // to be the current memory space - do not free it quite yet!

       // Retrieve the current XML data and length...
       // (xmlPointer contains the address of the first byte of the allocation)
       // (xmlLength informs us how much memory has been used by XMLi)
       // xmlData (based on pointer) is used to print to the screen
       xmli_getCurrentData(xmlPointer : xmlLength);

       // Print the data sitting on the pointer the console...
       example_print( 'The value on the pointer is:' + CRLF);
       example_print( %subst(xmlData : 1 : xmlLength) + CRLF);
       example_print( 'Press ANY KEY to close the window' + CRLF);
       example_pauseScreen();

       // Use the address of char1024 and the data length to write to the IFS...
       xmli_writeToFile( '/HOME/XML_TEST/Example09.xml'
                        : %addr(xmlData)
                        : xmli_getCurrentLength()
                        : XML_ENCODING_UTF8);

       // Tell XMLi you don't want it to use the variable anymore...
       xmli_freePointer(pointer);

       // Free the memory allocated...
       dealloc(e) pointer;

       *INLR = *on;
       return;

      /end-free 


XMLI1: Write XML to Managed Memory

	 
	 H OPTION(*NODEBUGIO:*NOEXPDDS:*SRCSTMT)
     H DFTACTGRP(*NO) ACTGRP('QILE')

      **************************************************************************
      * This example uses XMLi to write XML to Managed Memory.
      *
      * To use XMLi you simply tell it to use your pointer and then tell it
      * what you want to write. XMLi works out where to write and how to format
      * the XML for you.
      * When you have created your XML simply tell XMLi to no longer use your
      * pointer.
      *
      * This example will print the contents of the memory to the console.
      **************************************************************************

      // BNDDIR for XMLI1...
     H BNDDIR('XMLILIB/XMLI1')

      // BNDDIR for displaying example results (DO NOT USE IN PRODUCTION)
     H BNDDIR('QC2LE')

      **********************************************************************
      // Copybook for XMLI1...
      /include xmlilib/qcpylesrc,xmli1_h
      *********************************************************************

      // Copybook for displaying example results (DO NOT USE IN PRODUCTION)
      /include xmlilib/qrpglesrc,example_h
      **********************************************************************

      // Program variables...
     d xmlPointer      s               *
     d xmlLength       s             10i 0
     d xmlData         s            512a   based(xmlPointer)
      *********************************************************************
      /free

       // Tell XMLi to manage the memory...
       xmli_useManagedMemory();
       xmli_setFormat(XML_FORMAT_SIMPLE);

       // Build some XML (with a declaration)...
       xmli_addDeclaration(XML_ENCODING_IBM037 : XML_STANDALONE_YES);
       xmli_openTag('root');
         xmli_addAttribute('timestamp' : %char(%timestamp));
         xmli_addElement('element1' : 'value1');
         xmli_addElement('element2' : 'value2');
         xmli_addElement('element3' : 'value3');
         xmli_openTag('sub-element');
           xmli_addAttribute('attr1' : 'Attribute Value 1');
           xmli_addAttribute('attr2' : %char(%date():*USA));
           xmli_addData('Here is some data to go in sub-element');
         xmli_closeTag('sub-element');
       xmli_closeTag('root');

      // At this point the xml has been written and stored by XMLi
       // If the current data is to be retrieved then the Managed Memory
       // needs to be the current memory space - do not free it quite yet!

       // Retrieve the current XML data and length...
       // (xmlPointer contains the address of the first byte of the allocation)
       // (xmlLength informs us how much memory has been used by XMLi)
       // xmlData (based on xmlPointer) is used to print to the screen
       xmli_getCurrentData(xmlPointer : xmlLength);

       // Print the data sitting on the pointer the console...
       example_print( 'The value in Managed Memory is:' + CRLF);
       example_print( %subst(xmlData : 1 : xmlLength) + CRLF);
       example_print( 'Press ANY KEY to close the window' + CRLF);

       // Use the address of char1024 and the data length to write to the IFS...
       xmli_writeToFile( '/HOME/XML_TEST/Example10.xml'
                        : %addr(xmlData)
                        : xmli_getCurrentLength()
                        : XML_ENCODING_UTF8);

       // Tell XMLi you don't want it to manage the memory anymore...
       xmli_freeManagedMemory();

       example_pauseScreen();

       *INLR = *on;
       return;

      /end-free