For XML invoicing there are strict rules for the output XML file layout and contents. Such rules are normally described in quite complex documents and XSD’s (XML Schema Definitions). The problem with such descriptions is normally, that it is hard to ‘translate’ such descriptions into a real example.
It is our experience, that getting a proper XML output sample makes the process much more easy.
It is possible to manually build up the complete XML file manually, but it is recommended import a sample XML file instead, and map the input spooled file data into that.
Manual build up/edit of the XML structure is described here, but with XML+ there are some extra tools available to build up the output XML format. You can e.g. let InterForm400 insert a subtree for each detail line in the input spooled file via option Line type repeats.
Below some specifics for the XML+ module are described.
The XML structure is defined via this option:
Change XML definition XML300D
XML definition name . . : AAAXML Description . . . . . . : XML Demo splf to Demo XML
Type options, press Enter. 1=Select
Opt Definition XML output file and exit program Page type definitions Line type definitions 1 XML structure and data Line type repeats XML file validation
F3=Exit F12=Cancel F13=Select spooled file
|
After selecting this option, you will see this screen:
Work with XML nodes XML350D
XML definition name . : AAAXML
Position to . . . . . . Sequence number
Type options, press Enter. 2=Change 3=Copy 4=Delete 5=Display 12=Field definitions
Opt SeqNbr XML path 10 /Root 20 /Root/Document 30 /Root/Document/DetailLine 40 /Root/Document/DetailLine 50 /Root//Document 60 /Root/Document/DetailLine 70 /Root/Document/DetailLine 80 /Root/Document/DetailLine 90 /Root/Document/DetailLine 100 /Root/Document/DetailLine 110 /Root/Document/DetailLine More... F3=Exit F6=Create F10=Service functions F11=View 2 F12=Cancel
|
With F10=Service functions you have some extra features compared to XML classic:
Service functions
2. Import xml file from stream file in /APF3812Home/work 4. Copy from imported xml file to current definition
Option ===> F3=Exit F12=Cancel
|
Each option is described below:
With this you can copy nodes in the output XML structure. After selecting this you state the interval of lines to copy and the destination line number. If you e.g. have an XML file with these lines:
Work with XML nodes XML350D
XML definition name . : AAAXML
Position to . . . . . . Sequence number
Type options, press Enter. 2=Change 3=Copy 4=Delete 5=Display 12=Field definitions
Opt SeqNbr XML path 120 /Root/Document/DetailLine 130 /Root/Document/DetailLine 140 /Root//Document 150 /Root/Document/DetailLine 160 /Root/Document/DetailLine
End F3=Exit F6=Create F10=Service functions F11=View 2 F12=Cancel
|
Then you can copy lines 140-160 and insert them at the end like so:
Copy line(s)
Node sequence . . . . . 140 - 160
Insert at node sequence 170
F3=Exit F12=Cancel
|
Whereby the result will look like this:
Work with XML nodes XML350D
XML definition name . : AAAXML
Position to . . . . . . Sequence number
Type options, press Enter. 2=Change 3=Copy 4=Delete 5=Display 12=Field definitions
Opt SeqNbr XML path 120 /Root/Document/DetailLine 130 /Root/Document/DetailLine 140 /Root//Document 150 /Root/Document/DetailLine 160 /Root/Document/DetailLine 170 /Root//Document 180 /Root/Document/DetailLine 190 /Root/Document/DetailLine
End F3=Exit F6=Create F10=Service functions F11=View 2 F12=Cancel
|
With this option you can copy an existing XML file and use the structure from this when you are mapping data from the input spooled file into the output XML file. The XML file must be placed in the IFS inside /APF3812Home/Work.
When you select this option you will see this:
Import xml file from stream file in /APF3812Home/work
Stream file name . . . MyFile.xml
Option . . . . . . . . 1 1=Import only, 2=Import and append to current definition F3=Exit F4=List F12=Cancel
|
You can press F4 to view all XML files inside /APF3812Home/Work, and here select the stream file with option 1 to copy it into the screen or type in the name manually.
Here you have these options:
1=Import only
With this option you can later chose to copy fractions of the XML file instead of the complete file. The contents is on placed in ‘limbo’ for future copies. The fractions can be copied with option 4. Copy from imported xml file to current definition.
2=Import and append to current definition
This option imports the selected XML file, and copies/appends it to the current list of nodes. All contents is copied.
With this option you can view the original XML file, that you have previously imported. You can view the complete XML file structure, fields and contents.
Before you can use this option you need to have imported an XML file first. The import is done via option 2. Import xml file from stream file in /APF3812Home/work as described above. You can check out the contents of the import XML file via option 3. Display imported xml file. You specify the lines to copy and destination like so:
Copy from imported xml file to current definition
Node sequence . . . . . 1 - 10
Insert at node sequence 100
F3=Exit F12=Cancel
|
If the destination node sequence number already exists, then the node(s) are inserted just above this sequence number.
With this option all line sequence numbers are changed, so that the interval is 10.
The assignment of values to fields and attributes is generally described here. However this does not describe the option to use Xpath to assign a value. If you select option 12=Field definitions for a node, then you can work with the fields/attributes in this node. If you here edit a field/attribute you will see this:
Change field definition XML361D
XML definition name . . : AAAXML Sequence number . . . . : 10 XML path . . . . . . . . : /Root
Field sequence . . . . . . 10 Field . . . . . . . . . . Demo Attribute . . . . . . . . Description . . . . . . .
Page type(s) . . . . . . . Line type . . . . . . . . Use relative line . . . Y=Yes, N=No Line . . . . . . . . . . . From position . . . . . . To position . . . . . . . Length . . . . . . . . . .
Operator . . . . . . . . . F4=List Compare value . . . . . . More... F3=Exit F4=List F12=Cancel F13=Select spooled file
|
Press <Page Down> for this screen to appear:
Change field definition XML361D
XML definition name . . : AAAXML Sequence number . . . . : 10 XML path . . . . . . . . : /Root
Xpath expression . . . . . 100
Decimal positions . . . . 2
Functions . . . . . . . .
F3=Exit F4=List F10=Constant/xpath End F12=Cancel F13=Select spooled file
|
You can select between Constant and Xpath with the F10. In the example above a constant is defined and combined with the ‘Decimal positions’ option in the bottom. The result is, that the numeric value, 100 is inserted in the output XML file as ‘100.00', because:
a) We set the number of decimal positions to 2.
b) The decimal point is a dot in ‘correct’ XML format - independent of the local preferences ;-)
An Xpath expression can refer to the contents of the output XML file, but it can also refer to an internal field, which is not included in the final XML output.
If you create multiple Xpath expressions with references to other nodes, which may also use Xpath functions, then InterForm400 will automatically calculate the expressions in the correct order.
Xpath is e.g. described here:
http://www.w3schools.com/xsl/xpath_intro.asp
You can also find Xpath examples in the InterFormNG manual.
If you want to test various Xparth expressions you can use these sites:
http://www.freeformatter.com/xpath-tester.html
http://www.xpathtester.com/xpath
If you e.g. want to calculate the sum of the amounts in all detail lines in this XML file:
Then you can use this Xpath expression:
sum(/Root/DetailLine/Amount)
Please note, that all Xpath functions must be written in lower case.
An internal field must be defined in a namespace, which refers to http://www.interform400.com in the URI. The URI should just start with this, so e.g. http://www.interform400.com/internal is also a valid URI.The name of the namespace can be selected freely, but a suggestions could be ‘if’ or ‘internal’. With this in mind we add such a namespace in the root node of the output XML file like so:
Copy field definition XML361D
XML definition name . . : AXMLDEMO Sequence number . . . . : 1 XML path . . . . . . . . : /root
Field sequence . . . . . . 1 Field . . . . . . . . . . Attribute . . . . . . . . xmlns:if Description . . . . . . .
Page type(s) . . . . . . . Line type . . . . . . . . Use relative line . . . Y=Yes, N=No Line . . . . . . . . . . . From position . . . . . . To position . . . . . . . Length . . . . . . . . . .
Operator . . . . . . . . . F4=List Compare value . . . . . . More... F3=Exit F4=List F12=Cancel F13=Select spooled file
|
Page Down shows this:
Copy field definition XML361D
XML definition name . . : AXMLDEMO Sequence number . . . . : 1 XML path . . . . . . . . : /root
Constant . . . . . . . . . http://www.interform400.com
Functions . . . . . . . .
F3=Exit F4=List F10=Constant/xpath End F12=Cancel F13=Select spooled file
|
After we have defined a namespace, which refers to http://www.interform400.com, we can now create fields, that refers to this namespace in the syntax <namespace>:<field> like below:
Copy field definition XML361D
XML definition name . . : AXMLDEMO Sequence number . . . . : 1 XML path . . . . . . . . : /root
Field sequence . . . . . . 1 Field . . . . . . . . . . Attribute . . . . . . . . if:demo Description . . . . . . .
Page type(s) . . . . . . . Line type . . . . . . . . Use relative line . . . Y=Yes, N=No Line . . . . . . . . . . . From position . . . . . . To position . . . . . . . Length . . . . . . . . . .
Operator . . . . . . . . . F4=List Compare value . . . . . . More... F3=Exit F4=List F12=Cancel F13=Select spooled file
|
The value of the field can be set to data found in the input spooled file, an Xpath expression referring to field from either the XML and/or internal fields and constants.
When you refer to an internal field in an Xpath expression you can do it like so:
concat(/*:root/if:demo,'x')
In this Xpath expression we are adding an ‘x’ to the end of the internal field, demo with the Xpath command, concat.
InterForm400 comes with some extra, internal Xpath functions - apart from the many, normal Xpath functions. Before you can use these extra functions you need to add an extra namespace with the URI: http://www.interform400.com/functions.
The namespace should be added in the root node, and can be defined like this:
Copy field definition XML361D
XML definition name . . : AXMLDEMO Sequence number . . . . : 1 XML path . . . . . . . . : /root
Field sequence . . . . . . 1 Field . . . . . . . . . . Attribute . . . . . . . . xmlns:fnc Description . . . . . . .
Page type(s) . . . . . . . Line type . . . . . . . . Use relative line . . . Y=Yes, N=No Line . . . . . . . . . . . From position . . . . . . To position . . . . . . . Length . . . . . . . . . .
Operator . . . . . . . . . F4=List Compare value . . . . . . More... F3=Exit F4=List F12=Cancel F13=Select spooled file
|
The screen shown with <Page Down> should be setup like this:
Copy field definition XML361D
XML definition name . . : AXMLDEMO Sequence number . . . . : 1 XML path . . . . . . . . : /root
Constant . . . . . . . . . http://www.interform400.com/functions
Functions . . . . . . . .
F3=Exit F4=List F10=Constant/xpath End F12=Cancel F13=Select spooled file
|
Above we define a namespace called fnc, but the name, fnc can be freely chosen. You just need to refer to the same namespace, when you want to use the internal functions.
These internal Xpath functions are available:
DateAddDays
This function is able to add days to a specific date. The format is:
DateAddDays(<Date>,<Days to add>), where the Date format is written as ‘yyyy-mm-dd’.
Example:
fnc:DateAddDays(/default:Invoice/cbc:IssueDate , /default:Invoice/internal:PayDays)
NewLine
This function inserts a new line in the XML output file.
Example:
concat(../internal:paytext1, '.', fnc:NewLine(), ../internal:paytext2)
Base64EncodeFileData
Converts a stream file into a Base64 data stream, which can be inserted in the XML file.
Example:
fnc:Base64EncodeFileData('/pcdata/temp/demo.pdf')
PropertiesFileGetByKey
This function can be used for getting a value by lookup in a properties file (a stream file) with a key. A properties file an be created with the command:
APF3812/CRTPRPF. You can create the properties anywhere in the IFS and you need to state the full path. (The folders in the path must exist).
The properties file can be edited with e.g. Notepad or with the command:
APF3812/WRKPRPFE e.g. like this:
APF3812/WRKPRPFE STMF('/apf3812home/xml/translation_de.xml')
In the command you use e.g. F6 to add new entries in the properties file.
This properties file can look like this:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
-<properties>
<entry key="Invoice">Rechnung</entry>
<entry key="Total_amount">Gesamtbetrag</entry>
<entry key="VAT">Mehrwertsteuer</entry>
</properties>
You can retrieve a value from a property file with the command, RTVPRPFE in a program:
APF3812/RTVPRPFE STMF('/apf3812home/xml/translation_de.xml') KEY(Invoice) VALUE(&RETURNVAL)
The command above retrieves the value from the properties file, which corresponds to the ‘Invoice’ key, which in this example could be the german word for Invoice i.e. ‘Rechnung’. The Xpath function below does the same:
Example:
fnc:PropertiesFileGetByKey('/apf3812home/xml/translation_de.xml' 'Invoice')
Please note, that the encoding of the stream file must be set as the attribute of the XML stream file is used for the lookup. You can display the encoding with this command:
QSH CMD('attr /apf3812home/xml/translation_de.xml CCSID')
If the attribute does not fit the contents, then you can set it with either of these commands:
(In these examples the CCSID is set to 1208, which is the same as UTF-8).
CHGATR OBJ('/apf3812Home/xml/translation_de.xml') ATR(*CCSID) VALUE(1208)
QSH CMD('attr /apf3812Home/xml/translation_de.xml CCSID=1208')
Please note, that you need to precede the internal XPath commands with the namespace, that you defined yourself.
Some nodes/subtrees in the output XML file should be repeated for each detail line in the input spooled file. You define exactly which nodes/subtrees to repeat via this option:
Work with repeat line types XML320D
Position to . . . . . . Line type
Type options, press Enter. 2=Change
Opt Line type From sequence To sequence DETAIL 40 60
End F3=Exit F12=Cancel
|
All line types you have defined are shown in the screen above. For each of the line types, you can tell InterForm400 to repeat an interval of the sequence numbers shown in option XML structure and data. In the example above the sequence lines 40-60 are repeated for each DETAIL line.