Monday, May 8, 2017

XML parsing in AS400 (IBM-i) using XML-INTO

Hello Friends,

If you are new in working with XML in AS400 or just starting to do some XML parsing, this article will be useful to you.

XML-INTO is the op-code used to parse the XML document and retrieve the values directly into the variables in RPGLE.

Previously I saw many examples using DOM parser but it is complex for any beginners. But IBM introduced XML-INTO op-code and made the XML parsing much easier. Let us directly jump into syntax and examples.

Syntax:

xml-into <VariableName> %xml(<filename> : options)

There are couple of options which are considered while parsing the xml. We will see one by one.

Mostly the <variablename> will be a data structure which matches with the xml structure. 

Simple XML:


RPGLE:



Output:

Options in xml-into:

Case=any

In general XML tag names should match with RPG variables with case sensitive. But using case=any option we can eliminate it.

Doc=file

This tells the op-code that xml data source is coming from a file document. In this case, the first parameter of %XML function will be file name.

Allowmissing=yes

Sometimes if we are having missing fields in XML document

Allowextra=yes

Sometimes if we get extra tag in the XML (not defined in DS)

In other words, if u expect all the DS fields are mandatory in your XML you can give allowmissing=no and handle the exception and allowextra=no will not accept any extra tag to come in your xml.

In most cases, we use both as ‘yes’ and handle the exception in program.

Path=”string”

Using path option you can directly read any particular tag value. We will see it deeper in coming examples.

A complex XML:

Let us look at below example which has nested tags, attribute value and also repeating a particular tag number of times. 



Here we need to know how to define a nested data structure and how to find number of times a tag being repeated. Fortunately, xml-into offers an easy way to do that.

And trust me we can just parse all the values with single statement J

How to form nested Data Structure:



If you look closely, we have split the group of tags into separate DS and nested into main Customer DS using LikeDS keyword. The reason for CtInfo_T & Item_T is declared as Template but Order_T & OrdDet_T are declared as Qualified because, if we are going to have any nested DS then the parent DS should be declared as Qualified.

Take a note on DepartmentNumber. This exceeds normal variable length of 15 char while defining in RPGLE. So if we have variable length more than 15 char then we have to write the full name followed by three dots. Thus system will look for its declaration in next line. (in our case 2S 0)

Count_Item:

Do notice this variable Count_Item is an extra field apart from XML fields. When we need to parse multiple occurrence tags (in our case <item> tag) then we have to define a variable next to repeated tag so that system will automatically give us the number of repetition in this variable.

RPGLE code:



Please note on the countprefix option. We are saying the system to return the count of repetition under the variable has prefix “count_”

i.e. for item tag the count variable should be “count_item”

if we change “countprefix=cnt_” then in our DS, the variable should be “cnt_item”

here we go, we got all the values, and also the count_item has number of repetition as “3”.


With this in hand, we can very well do our program logic and proceed further.

One last example using path option:

Using path we can directly read any segment of xml. For example, I want to retrieve OrderNumber alone from the XML. Then,


Do note that if we are fetching value of a single tag directly then variable name to receive the value may not need to be the same xml tag name. (Here OrdNum is used).

Hope this post gives you enough idea to get start with xml-into method of parsing. It is really very useful as you can see it requires very minimal amount of coding. I will come with another topic soon. Until then…

Have fun..!!! Happy coding…!!!

14 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete



  4. dfilename s 50
    doptions s 150
    *
    dcustomer ds qualified
    dname likeds(full_name)
    did 1s 0
    dcount_custom 5i 0
    *
    dfull_name ds qualified dim(2)
    dfirst 10
    dlast 10
    c
    /free
    options = 'case=any doc=file ' +
    'allowmissing=yes allowextra=yes ' +
    'countprefix=count_';
    Filename = '/qibm/two.xml';
    xml-into Customer
    %xml(%trim(Filename):Options);
    // dsply customer;
    *inlr = *on;

    /end-free

    output as
    EVAL customer
    CUSTOMER.NAME.FIRST(1) = ' '
    CUSTOMER.NAME.LAST(1) = ' '
    CUSTOMER.ID(1) = .
    CUSTOMER.COUNT_CUSTOM(1) = 16448
    CUSTOMER.NAME.FIRST(2) = ' '
    CUSTOMER.NAME.LAST(2) = ' '
    CUSTOMER.ID(2) = .
    CUSTOMER.COUNT_CUSTOM(2) = 16448

    Am unable to get the desired output where I have 2 customers with 2 id

    as
    Gnani
    s
    1

    Rach
    s
    2

    ReplyDelete
  5. Hi Mohammed,

    I tried to use youe example and I have this problem.
    My XML file has a tag beginning with




    IT
    03032810164


    CAPGEMINI BS SPA

    RF01


    VIA ENRICO MATTEI , 1
    30020
    MARCON
    VE
    IT


    VE
    210000
    1000000.00
    SU
    LN




    Thanks
    Bye

    ReplyDelete
  6. Excuse me but browser converted the statement... Sorry

    ReplyDelete
  7. ?xml version="1.0" encoding="UTF-8"?>
    p:FatturaElettronica versione="1.1"
    xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
    xmlns:p="http://www.fatturapa.gov.it/sdi/fatturapa/v1.1"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    How can i ignore the statement beginning with p:FatturaElettronica ?

    Thanks

    ReplyDelete
    Replies
    1. Buongiorno Filippo, ho trovato un tuo vecchio post dove chiedevi spiegazioni per convertire l'xml della fattura elettronica con la tecnica xml-into.
      Ci sei riuscito ? Se si, volevo chiederti se potevi mandarmi un esempio di come hai fatto perchè io ci sto provando ma non ci riesco.
      Grazie per l'aiuto che potrai darmi.
      Luca

      Delete
  8. Hi yusuf, thanks for this very useful post. I want to save the parsed data into a member of a pf. we can allocate MBR , ovrdbf and call this rpg where we need to assign the ds fields to file fields and write. Do you have any other ideas .. Thanks

    ReplyDelete
  9. tried your example as it is but getting this error:-
    Message . . . . : Preparation for XML parsing failed with message CPE3025.
    Cause . . . . . : An RPG procedure attempted to perform an XML parsing
    operation. Either the document could not be opened, or CCSID translation
    could not be done. The actual document is '/HOME/i0rs01hu/input3,xml'; *N
    indicates that the XML document was not an external file.
    Recovery . . . : Check the job log for a complete description of message
    CPE3025, and contact the person responsible for program maintenance.

    ReplyDelete
  10. this nice article. please also how to pick the value EA from below example
    1.0

    ReplyDelete