Content Conversion for ‘n’ Nested Structures( XML -> Flat File) Using Adapter Module – Receiver
Introduction:
This blog describes the configuration steps for converting the XML Data with nested hierarchies to FlatFile using custom Adapter Module
ContentConversionBean ( Direction -> Receiver ).
Pre-Requisites:
For novice users, Please read the link provided in help.sap.com related to File Content Conversion
Java Version:
This adapter module is written using JDK 1.5 API’s, so before deploying the Adapter Module (.ear file) make sure the JDK version 1.5 and above.
Problem:
Many Times, there are requirements where XML data in nested hierarchies needs to be converted into Flat File. Standard File Adapter or Standard Adapter Module supports only 3 nested levels of XML to Flat File. These requirements can be accomplished using Java Mapping. The Java Mapping is confined to that particular interface and it cannot be re-used for more than one interface, and hence it cannot be re-used for other scenarios.
Solution:
I have created a Generic Adapter Module to address the above problem for converting XML Data( with Nested Levels) to Flat File.
This module uses the most of the standard FCC parameters and the use of the those parameters are listed in the Table2.
Table 1:
The following properties should be configured only in the module configuration of the channel.
Property Name | Required/Optional | Description |
---|---|---|
Direction | Required | If the module used in sender channel provide the value as sender and if it is used in receiver channel specify receiver |
Configuration_Mode | Optional |
Configuration_Mode contains either file or local as the value.
|
File_Path | Optional |
Note: Properties file should be stored in the NFS file system of SAP PI. |
Table2 :
The following properties can be specified either in the file or in the Module Configuration of the channel depends on the value specified in the Configuration_Mode property specified in the Table1.
FCC Properties in the Receiver Side
Property Name | Required/Optional | Description |
---|---|---|
RecordSetName.recordSetStructure | Optional |
Specify the recordset names and the cardinality of substructures as follows: Here NameA, NameB,… is the recordset Names nA specifies the cardinality |
RecordSetName.fieldNames | Optional | Specify the fieldNames separater by comma (,) which belongs to the corresponding recordSet structure |
RecordSetName.endSeparator | Optional |
If you want to define an additional string as a separator after the last column in a row, specify it here. The system skips this separator when it processes the last column (otherwise the system would treat it as part of the last column). Note: if fieldNames property is defined for a recordSet, then endSeparator is required for that corresponding recordSet. |
RecordSetName.fieldSeparator | Optional |
If you make an entry here, the Module expects that the structure contains the specified character string (one or more characters) as a separator between the individual columns. If you have not made an entry for fieldFixedLengths , this is the only specification to identify the individual columns in a row. |
RecordSetName.fieldFixedLengths | Optional |
If you make an entry here, the Module expects a character string that contains the lengths of the structure columns as arguments separated by commas. If you also specify a separator for the columns, you must not add its length to the length of the columns. This entry is mandatory if you have not made an entry for RecordSetName.fieldSeparator |
RecordSetName.fixedLengthTooShortHandling | Optional |
Specify how you want the system to respond when column widths in the actual document exceed those defined in RecordSetName.fieldFixedLengths. The following values are permitted: Error -> Document processing is cancelled. Cut -> The value is cut to the maximum permitted length. Ignore -> The value is accepted even though its length exceeds the permitted value. Subsequent columns are moved accordingly. Note : This property will be used only RecordSetName.fieldFixedLengths is configured. |
How to create the Properties file:
- Open any text editor
- Save it with extension .properties
- Each and every property occurs in combination of key and value.
Eg: propertyname=propertyvalue
Comparison of XML Terminology & FCC Terminology with respect to FCC Configuration:
- XML Document can have only one root element which is parent of all the tags.
In FCC terminology, the name of the root element needs to be specified in the DocumentName property. - In XML terminology, if a Tag contains child tag then the parent tag is termed as Segment.
In FCC terminology, segment is nothing but recordset. - In XML terminology, if a Tag does not contains any child tag, then it is termed as field.In FCC terminology, field remain the same ie.field itself.
Sample XML Example:
- In the above xml, Message is the root element which needs to be specified in FCC as DocumentName=Message
- In the above XML, Message Tag contains 2 fields, in FCC it needs to be specified as root.fieldNames=Field1,Field2
- In the above XML, Message Tag contains 2 segments namely Details1, Details2, in FCC it needs to be specified as root.recordsetStructure=Details1,1,Details2,1
Here recordsetStructure property is used to specify the list of segments and their corresponding cardinality should appear under the root element. - Since the fieldNames property is configured for the root element, either the fieldSeparator property or fieldFixedLengths property needs to be specified and also endSeparator needs to be specified.
eg: root.fieldSeparator = ,
root.fieldFixedLengths=5,4
root.endSepartor=’nl’( here ‘nl’ specifies the end line) - In the above XML, Details1 recordset/segment contains the fields which needs to be specified in FCC as root.Details1.fieldNames=Field3, Field4.
- Since the fieldNames property is configured for the root.Details1 either the fieldSeparator property or fieldFixedLengths property needs to be specified and also endSeparator needs to be specified.
eg: root.Details1.fieldSeparator = ,
root.Details1.fieldFixedLengths=5,4
root.Details1.endSepartor=’nl’( here ‘nl’ specifies the end line) - Points 5,6 applies for the Details2 recordset/segment as well.
- In the above XML, If Details1 or Details2 further contains segments then it needs to be specified in FCC as root.Details1.recordsetStructure=Details3,* ( * specifies 0 or more ) or root.Details2.recordsetStructure=Details4,2 and so on you can build nested hierarchies.
Scenario 1:
The below snapshot depicts the xsd which is created with 5 levels of depth
Module Configuration:
In the below configuration, Configuration_Mode is specified as file, we have specified all the FCC properties in the file and stored in the NFS path and specified the path of the file to File_Path property.
The advantage here is, user no need to modify/change the channels in order to change the FCC property.
If the Configuration_Mode is either not specified or configured as local, then all the FCC properties should be configured in the Module Configuration
Input XML Data with Nested Hierarchies:
FCC Configuration:
Output Flat File:
Scenario 2: This scenario explains how to use the RecordSetName.fixedLengthTooShortHandling
Input XML Data:
FCC Configuration:
Output Flat File:
Note : In the above FCC, fixedLengthTooShortHanding propery will be effective only if the fieldFixedLengths property is configured for the recordset
Use the below link which explains conversion of FlatFile to XML with Nested Structures,
File Content Conversion for Deeply Nested Structures – Sender
Disclaimer:
- This Module is optimized to process messages with an approximate payload size <= 5 MB.
- This Module will not work with messages having attachments.
New NetWeaver Information at SAP.com
Very Helpfull