The XML user exit programs can be called from various functions while the XML file contents is built up, and also after the XML file has been created.
In the example below we imagine, that we want to do a lookup (e.g. in an external database) to set a dynamic value of a field in the output XML file.
The example refers to the setup, that is done in the sections below for the InterForm400 demo spooled file.
In this example we want to use positions 57-60 in line 13 as a customer number and insert a new field, Email, which should contain the email address of this customer, as the email address is not found in the input spooled file.
The XML exit program is based on the demo source member, XMLEXIT (RPGLE program) placed in the source file APISRC in library, APF3812.
You should keep the original source member, copy it to your own source file, and also compile it to your own library, and not place the compiled object in the APF3812 library.
In this example I have copied and changed the demo source to this source:
F********************************************************************** F* * F* XEXITFNC: * F* *START = Intial call before any processing * F* *OPEN = Open new XML file (File name in field XVALUE) * F* *DATA = Field or attributte value (Value in field XVALUE) * F* *CLOSE = XML file closed (File name in field XVALUE) * F* *END = End processing * F* * F********************************************************************** C *ENTRY PLIST C PARM XEXITFNC 10 C PARM XDEF 10 C PARM XPAGE 7 0 C PARM XLINE 3 0 C PARM XPOS 3 0 C PARM XPAGTYP 10 C PARM XLINTYP 10 C PARM XPATH 256 C PARM XFIELD 50 C PARM XATR 50 C PARM XVALUE 256 C PARM XVALUE2 256 C SELECT C XEXITFNC WHENEQ '*DATA' C exsr data C XEXITFNC WHENEQ '*END' C SETON LR C ENDSL C RETURN C* c data begsr c if XFIELD='Email' C eval XVALUE2=' ' c if %SUBST(XVALUE:57:4)='1001' c eval XVALUE2='email1001@mydomain.com' c endif c if %SUBST(XVALUE:57:4)='1003' c eval XVALUE2='email1003@mydomain.com' c endif c if %SUBST(XVALUE:57:4)='1004' c eval XVALUE2='email1004@mydomain.com' c endif c eval XVALUE=XVALUE2 c endif c endsr
|
So as you can see the program can be called in 5 situations and we concentrate on the third and fifth:
When the program is called with the value *DATA in the paramater, XEXITFNC, then we can update the value of a field in the output XML file.
When the program is called in this way, then the XFIELD contains the name of the field in the XML file, that is to be updated, and the XVALUE is the current value of this field - as stated in the XML definition.
During the call of the program we can change the value of XVALUE to set a different value for the field in question, so that is what is done in the program above:
If the name of the field is Email, then we test the contents of specific positions in the field. If they are either 1001, 1003 or 1004, then we set a return value, which is the email address.
If none of the values 1001, 1003 or 1004 are found, then the value of the Email will be blank.
You also need to change the owner of the program to QSECOFR. This can be done with this command:
CHGOBJOWN OBJ(<library>/<program name>) OBJTYPE(*PGM) NEWOWN(QSECOFR)
- or InterForm400 can do this change, when you add the reference in the XML definition.
The only thing missing now is to setup the XML definition accordingly.
First we edit the XML definition and insert the reference to our program by selecting '1' for this option: XML output file and exit program
Change XML definition XML300D
XML definition name . . : XML_DEMO Description . . . . . . : Demo: Convert demo spooled file into XML
User exit program . . . . XMLEXIT Name, *NONE Library . . . . . . . . MYLIB Name, *LIBL
|
Now we just need to define the field, Email, that our program has been built for.
We add it via option 1 for this: XML structure and data
For the example in the following sections I have added a new field in this path: /Root//Document:
Change field definition XML361D
XML definition name . . : XML_DEMO Sequence number . . . . : 2 XML path . . . . . . . . : /Root//Document
Field sequence . . . . . . 3 Field . . . . . . . . . . Email Attribute . . . . . . . . Description . . . . . . .
Page type(s) . . . . . . . PAGE1 Line type . . . . . . . . Use relative line . . . Y=Yes, N=No Line . . . . . . . . . . . 13 From position . . . . . . 1 To position . . . . . . . 80 Length . . . . . . . . . .
Operator . . . . . . . . . F4=List Compare value . . . . . . More... F3=Exit F4=List F12=Cancel F13=Select spooled file
|
The interesting thing here is, that the spooled file text, that are selected (line 13, positions 1-80) is the input for the user exit program, so in this way the lookup in the program can e.g. substring multiple set of information from that line to do the lookup. (The max. width to transfer to the program is 256 characters).
Since we transfer spooled file data from position 1 in the spooled file, we can also refer to the exact positions in the user exit program as shown above.
The actual call of the exit program is set on the Email field, when you press <Page Down>:
Change field definition XML361D
XML definition name . . : XML_DEMO Sequence number . . . . : 2 XML path . . . . . . . . : /Root//Document
Constant . . . . . . . . .
Functions . . . . . . . . EXITPGM
End F3=Exit F4=List F12=Cancel F13=Select spooled file
|
The result is as expected, that we get a new field, Email in the output XML file for each document: